In the chuck below, we will make Seurat objects of all samples (and apply basic filtering based on absolute median deviation to remove outliers):

Description:
  • For each object, we keep all genes that are expressed in at least 0 cells, thus we keep all genes as this is required for the removal of ambient RNA (The Cellrange filtered_feature_bc_matrix does not contain genes that have no expression across all cells, but this is often not the case for the raw_feature_bc_matrix, and considering that both matrices will be used for the detection of ambient RNA it is not wise to filter genes with 0 counts in the filtered_feature_bc_matrix. However, this is not an issue if the user chooses to work with the filtered_feature_bc_matrix without including the raw_feature_bc_matrixfrom from the the start).
  • Similarly, for now we want to keep all cells that have at least 0 genes expressed. We will later filter out all cells that have not at least x-number of genes expressed after successfully removing ambient RNA. Keep in mind that in reality no cells will be found with 0 genes expressed anyway considering the Cellranger pipeline already removed empty droplets and cells containing <500 UMIs. However, if you choose to work with the raw_feature_bc_matrix, you can actually fish out cell that may truly have <100 genes and <500 UMIs. In that case, we will make sure that we remove droplets (cells) that have <100 genes by default. You can choose to change this parameter, but it is very unlikely to find real cells with <100 genes.
Results:
  • From now on you (the user) should keep an eye on the “the number of samples (cells)” in the chuck below. The number of samples in each filtering step will give you an idea how many cell you are losing in each step.
$`ileum_org_pig-G3_IL1_1-filtered_ref_GTF-incl_intr`
An object of class Seurat 
22040 features across 3163 samples within 1 assay 
Active assay: RNA (22040 features, 0 variable features)
 1 layer present: counts
  • After filtering the objects based on the absolute median deviation, you can take a close look at the number of samples again and see how many cell were removed when compared to the previous step:
    • Absolute median deviation threshold is set in a way to remove the very extreme cells in case some slipped through the Cellranger filtering.
    • The filtering here will often not remove more than 20-50 cells and will not impact the pre-processing algorithms.
    • This step does have great impact if you choose to work with the raw_feature_bc_matrix. For a good reason too… unless you are in love with empty droplets…
  • Again, in the chunk below you should see haw many cells you lost. when compared to the previous step.
$`ileum_org_pig-G3_IL1_1-filtered_ref_GTF-incl_intr`
An object of class Seurat 
22040 features across 3162 samples within 1 assay 
Active assay: RNA (22040 features, 0 variable features)
 1 layer present: counts

QC plots:

Description:
  • The number of unique genes detected in each cell:
    • Empty droplets and low quality cells often have very few genes and many 0 counts
    • Cell multiplets (doublets) often have very high gene count.
    • If you work with the filtered counts matrix as a starting point you will not find cells with <500 UMIs.
  • User expectation:
    • In general, you should have an expectation of home many genes/UMIs the majority of your cells contain. Most of the time, The UMI counts per cell should be at least ~500 (and ~200 genes), that is considered the low end of what you should expect. However, cell that express extremely low number of genes will have UMI count below ~500. The same is true for a failed experiments with degraded RNAs. Thus the user should have an clear expectation.
  • The percentage of reads mapped to the mitochondrial genome:
    • Often, dying cells (or low quality cells) have lots of mitochondrial contamination, possibly due to loss of cytoplasmic RNA from perforated cells. The reasoning is that mitochondria are larger than individual transcript molecules and less likely to escape through tears in the cell membrane.
    • Note that for single-nuclei samples, MT genes are often still present, but at much lower quantities when compared to single-cell data.
    • Mitochondrial QC metrics are calculates with the percentage of counts originating from a set of features.
    • We use the set of all genes starting with “MT-” or “mt-” as mitochondrial genes (which have been inserted/manipulated in ALL MT genes). (The Ensembl database is used to find the MT genes in the species!)
Results:
  • Barplots:
    • Representing the distribution and number of gene counts, transcript counts, and percentage of MT reads per cell. Generally, high fraction of MT reads in combination with low gene/transcript counts indicate stressed or dead cells. However, highly prolific stem or cancer-like cell are often rich in MTs, whereas some immune cells such as neutrophiles are in lower end of the spectrum in terms of gene and transcript counts.
    • The dashed red and orange lines represent the theoretical thresholds (Red: 10% MT, 200 nGenes, 550 nUUMIs. Orange: 7.5% MT)

Here we will visualize the distribution of nGenes and nUMIs and the complexity of the cells:

Description:
  • Terminology:
    • nFeature_RNA is the number of genes detected in each cell (violin plot).
    • nCount_RNA is the total number of molecules detected within a cell (UMIs) (violin plot).
    • percent.mt is the percentage of mitochondrial UMIs within a cell (violin plot).
    • Cell complexityis the proportion of nGenes raltive to the number of transcripts (RNA-molecules/UMIs).
    • Low complexity cells is a cell that has few genes, but more transcripts.
    • High complexity cells is a cell that more genes and less transcripts.
    • Dominant gene is a gene that has the hiighest expression in a cell relative to the other genes.
Results:
  • Violin plots:
    • Low nFeature_RNA for a cell indicates that it may be dead/dying or an empty droplet. It is usually accepted that cells that are poor quality are likely to have low genes and UMIs per cell, and correspond to the data points in the bottom left quadrant of the plot. Good cells will generally exhibit both higher number of genes per cell and higher numbers of UMIs. But be careful here, some cell types are known to have low genes and UMIs.
    • High nCount_RNA and/or nFeature_RNA indicates that the “cell” may in fact be a doublet (or multiplet). But be careful again, some cell types are known to have super high genes and UMIs (i.e. developing cells, cancer, stem-cells).
  • Percent-MT vs nGene / Percent-MT vs nUMI plot:
    • Again, for bad cell we expect to see the high percentage MT with low number of genes/UMIs (unless expected otherwise, e.g. cardiac cells).
    • The dashed read line represents a theoretical MT limit of 10% and orange 5%.
  • nUMIs vs nGenes plot (also log scaled version):
    • Empty droplets and low quality cells often have very few genes and many “0” genes/UMI counts (Minimum of 500 UMIs if you use the filtered counts matrix).
    • Cell multiplets (doublets) often have very high gene/UMI count.
    • Notice that cell with the highest mitochondrial genes are located in the bottom-left of the plot, indicating that these are truly bad cell considering they contain high MT percentage, but low number of genes/UMIs. Keep in mind that good cells could also have number of MT genes, these cells are often activated cells (i.e. Stem/cancer/cycling/developing cells). Now it could a little troubling if the majority of your high MT cells also contain many genes/UMIs, especially if you do not expect activated cell types in your data. You have to be aware with the type of cell you are working with.
    • In the nUMI vs nGenes plot we can also see the complexity of the dataset with potential errors. Generally, we expect a linear relationship between the number of genes and UMIs in this plot. If cells in the plot are skewed far from the middle line towards the bottom-right this could mean that the experiment has captured very few number of genes and those same genes have been sequenced multiple times. Similarly, if the cells are skewed towards the top-left this could mean that experiment has captured many genes, but they are not sequenced deeply enough (which results in low number of UMIs). Keep in mind that as a result of RNA degradation, a failed experiment could still give us a good plots.
    • The orange dashed lines show the theoretical lower limits of UMIs (550) and genes (200). The yellow dashed lines show the upper and lower quantiles of both number of genes and UMIs (default set between 2-98%). If you choose filter the number of genes and UMIs by user-defined quantiles, then the yellow dashed lines will be set at those numbers.
  • Complexity plot (the singular plot below):
    • Complexity can also be visualized by dividing the nGenes by nUMIs for each cell. Higher values indicate that we are getting shallower coverage of more genes, and lower values mean that we are seeing fewer genes overall.
    • Generally, we expect the novelty score to be above 0.80 (indicated with dashed red line).
    • As there is a linear relationship between the number of genes and transcripts for the majority of the cells, it is expected to find the highest probability at a genes/transcript ratio between 0.85-0.95, even for low-complexity cells. A large probability density at anything below 0.8 indicates a failed experiment, as insufficient genes have been captured in proportion to transcript counts.
  • Plotting complexity as function of percentage of counts per gene (the first trio plots below):
    • Complexity: Log10 - nUMIs vs nGenes: Again, make another plot as before (log10 - nUMIs vs nGenes plot), but now we fit a linear model and calculate the residual from the middle point for each cell. Now we can clearly visualize which cells have more transcripts vs genes relative to the middle-line (or vice versa). This is indicated by the strength of the blue or red color.
    • Residual vs Density: In this plot, we can see the frequency (density) of cells as a function is the residuals (i.e. deviation from the linear regression). What do you see here? A normal distribution or skewed towards the left or right? This density plot is simply an addition to the linear model and it is expected that you find the largest density around 0, meaning that the majority of the cells were indeed close to the middle line in the linear regression. Just like before, if the graphs is skewed toward the left (negative residuals), this means that you may have an undesired number of low-complexity cells. Likewise, if the graph is skewed towards the right side (positive residuals), then you may many high-complexity cells. Usually, such behavior is related to some sort of failed experiment.
    • Residual vs Percentage Largest genes: In this plot, for each cell, we calculate the gene with the highest percentage of reads and put against the residuals. You can now see a semi-density plot as before, but now with the actual cells. Do you see a pattern here? Do you see any low-complexity cells with a high percentage of a dominant gene? Ideally, we expect a volcano plot centered around the middle. If you have many low-complexity cells with a significantly inflated dominant gene, this might indicate bad cells. But first, we have to find out winch dominant gene they express to make a final conclusion if it is truly related to some biological reason or technical.
  • Plotting complexity and examining dominant genes (the final trio plots below):
    • Complexity by Largest Gene: This is the same linear plot as before, but now we visualize the most dominant gene per cell (top 8 out of total in the dataset). Do you see a pattern here or a specific gene that is expressed in low or high complexity cells? Often, the unusual populations in these plots can derive from the activity of a single gene, so now you have a chance figure this out… If these genes happen to be from a mitochondrial origin, then you are likely dealing with dead cells. Likewise, high expression of MALAT1 can also indicate dead cells.
    • Residuals vs Percentage Largest Genes: Same as before, but now with the dominant gene visualized. Which genes are the dominant ones in you off target populations? And does this meet your expectation?
    • Residuals vs Percentage Largest Genes + MT %: Same plot, but now with percentage MT. Do the off-target cell populations show high percentage of MT? And do find some correlation between this plot and the dominant genes from before (MT genes)?

`geom_smooth()` using formula = 'y ~ x'
`geom_smooth()` using formula = 'y ~ x'

Visualize the highy variable genes:

Description:
  • We first employ a log normalization method that normalizes the gene expression counts for each cell by the total expression and multiply this by a scale factor of 10,000 and log transform it to stabilize the variance so that larger values do not dominate over smaller ones.

  • Then the top 2,500 genes (user-adjustable) with largest standardize variance will be selected automatically and used for the clustering. By selecting highly variable genes, we ensure that house-keeping genes with similar expressions across different cells do not interfere with the unsupervised clustering.

  • Note that there is no definitive answer on how many genes one should include for clustering. Thus it is recommended to carefully consider the right number or by trying a range of 2000-5000 variable genes. Generally, low-complexity data (i.e. data with similar cells) will have lower number of variable genes when compared to complex tissue. By default, we will select 2500 highly variable genes.

Results:
  • Most Variable Genes:
    • The plot should not looks like a flat line. There should be a clear distribution of the genes with the most highly variable on the top. If there are no highly variable genes in your data, then you are likely dealing with cells that have similar expression levels of the same genes. This can drastically impact the clustering and ambient RNA correction as most downstream steps are computed only on these genes.
Finding variable features for layer counts

Unsupervised clustering: PCA

Description:
  • Here, we carry out a linear dimensional reduction using PCA on the scaled data containing the most variable genes (as chosen before):

    • Before putting the highly variable genes into PCA, we will specifically scale those genes so that they have a mean of 0 and a variance of 1. More specifically, For each highly variable gene, a regression model is build using that gene’s expression level across all cells, and then shift the residual to zero and divided it by standard deviation.
    • We are essentially scaling and centering these genes in the dataset, which standardizes the range of expression values. This will regresses out unwanted sources of variation such as technical noise and each gene will contributes similarly to the downstream steps. As a result, the PCA and clustering will not be dominated by the signal of a few highly-expressed genes.
  • The reason that we do a PCA is because we simply cannot work with this ultra high dimensional data for the downstream analysis. Instead we can look at which of the most variable genes explains most of the variance in the data.

  • Note the PCA is a suitable method, but has some disadvantages:

    • (I still believe that ML would be a better option here, but it is not benchmarked in single-cell data as an alternative to PCA).
    • PCA is very popular, but fails to capture all signals considering that 2D dimensionality reduction cannot capture faint signal.
Results:
  • PCA elbow plot: We will find the optimal number of dimensions for downstream analysis, based on:
    • PC where change in percent variation is more than 1%.
    • Or, PCs representing cumulative percent >90% and less than 5% associated with the single PC.
    • With each PC representing combined information of positive and negative correlated gene sets, the top PCs represent strong compression of the total dataset that can be used for further dimensionality reduction and clustering. If you find less than 10 PCs in the elbow plot, your data likely contains too few relevant genes for successful clustering. After all, we are looking for genes that can explain the variance in your cells, and if no such genes can be found (or too few of them) then the downstream steps will have difficulties to find the differences between your cells. However, if you are working with low-complexity data (e.g. similar cell types in different biological states) then you should to find fewer number of PCs.
    • The dashed red line in the plot shows the optimal number PC dimensions.

Final clustering (KNN (SNN)) using the most explained PCs and projection onto UMAP:

Description:
  • Original Louvain algorithm:
    • Based on the Euclidean distance in the PCA space, the pipeline carries out a K-nearest neighbor graph (k=20 by default) and refines the edge between any two cells based on shared overlap between their expression patterns using the traditional Jaccard similarity technique.
    • The clusters are then constructed by joining the groups interactively until it fully converges using the Louvain algorithm. Cells are then moved to a non-linear UMAP space for visualization. Here, we find that by using a resolution of 0.8, Louvain does a decent job in identifying sufficient number of communities for both high complexity (porcine ileum, with immune) and low-complexity data (porcine ileum organoid or tissue, no immune).
    • To resolution of 0.8 is set as default, but more research is required to use an adaptive resolution depending on the type of data as this parameter could greatly impact the number preliminary clusters that will be used by the ambient RNA correcting algorithm. As an experimental feature, you are allowed to change the resolution, which will impact the final number of cell clusters (not recommended).
    • In case you end up with too few cluster by the default settings, then it worth to try a resolution >0.8. If you have too few clusters, the ambient RNA correction might become biased (more on this later…).
Results:
  • UMAP plots: Number of genes/UMIs/MTs are shown per cell within each cluster:
    • These plots can give us an idea which cells (within clusters) contain low, medium or high number of genes and total UMIs.
    • Note that high number of genes or UMIs is not necessarily a bad thing, but is still highlighted with “purple”
    • In case of a failed experiment (low number of genes) due to significant population of cells with a low RNA content, these plots can show which groups of cells are affected. And if the same clusters contain high percentage MT genes, then it is likely that those cells are low-quality or dead.
    • How many cluster do you observe in total? Do you expect to see more (or less) based on what you already know about your samples?

SoupX Ambient RNA Removal:

Description:
  • Terminology:
    • Total contamination is the fraction of ambient RNA (for each gene) estimated from (semi)-empty droplets from the raw counts matrix.
    • Contamination fractions is the the estimated the number transcripts that are contributing to the previously calculated background contamination (from empty droplets) using the expression of several marker genes between cell-clusters where it does not belong. Here it is assumed that the abundance of genes that make up the background are not different between the cells.
  • The aim of SoupX is to estimate what fraction of the transcripts are derived as ambient in each droplet and to generate a corrected gene counts matrix with the contaminated counts removed. The algorthm take the following steps:
    • It first calculates the expression profile of the total contamination by estimating the ambient RNA expression from the raw counts-matrix obtained from the CellRanger output. Regardless of the user choice, in this step we always utilize the raw counts as this data contains information of empty droplets, which is an excellent candidate to analyze cell-free droplets that may contain ambient RNA for each gene. (If for some reason the raw counts are not available, SoupX will not run, and the pipeline will continue without the correction of ambient RNA).
    • Once the total contamination has been estimated, SoupX calculates the cell specific contamination level by using the previously found cell clusters. The point here is to find a set of genes in each cell that is known not be expressed in others, and then estimate the contamination fraction using the expression of that given gene in cells it does not belong. If you have too few cluster (due to lack highly variable genes and insufficient number PC dimensions), then it is advised to change number of UMAP dimensions >0.8. Try it out and see if anything improves. Usually, low number of clusters suggests low-complexity data (either biological or technical reasons). Remember that you can also leave out ambient RNA correction when dealing low-complexity if higher UMAP dimensions do not improve anything.
    • With the estimated contamination fraction and the background expression profile at our disposal, the contaminated counts for each gene within each cell can then be corrected.
  • Keep in mind that working with the raw counts matrix only will automatically filter cells/droplets that have less than 100 genes. This is a less aggressive filtering when compared to using the filtered counts matrix where Cellranger filtered out cells/droplets that contaied <500 UMIs. For this reason, do not be shocked to find higher ambient RNA contamination when working with the raw counts. The data will be successfully corrected most of the time (unless you are dealing with many degraded RNAs due to failed experiment).
Results:
  • Contamination Density plot (First plot):

  • Representing the probability distribution of estimated contamination fraction. The probability density is calculated by the aggregated set of genes per cells-cluster that have been used to find the contamination fraction. The final contamination fraction is then assigned to the one that occurs with the highest probability (indicated with a vertical red line). A probability distribution with a flat line (no clear peak) indicates failure of SoupX as none of the sets of genes have a preferred contamination fraction, while true estimates are more likely to have the same probability.

  • Barplot:

    • Representing the percentage of ambient RNA detected and removed from the data. A contamination level of around 10% is typical for non-nuclei fresh tissue sample.
  • Affected Markers Soup Markers (UMAP):

    • Representing the expression of marker candidates that were used for the estimation of the contamination fraction and their level of correction (pre and post Soup correction). By default, top 3 markers are used for plotting, but the user is provided with the option to choose anything between 0-100.
  • Affected User Genes (UMAP):

    • Representing the expression of user-defined genes and level of correction. For this to work the user must fill in the genes of interest in the gene.txt file.
  • Most Affected Genes (UMAP):

    • Representing the expression of most-affected genes and level of correction. As the most-affected genes are not expressed by many cells, these plots might not be very representative. This option is tuned off by default, but the user may turn it on and select the number plots.
  • Colors in the UMAP plots:

    • Red dots - the gene is strongly corrected in the cell
    • White dots - the gene is weakly corrected in the cell
    • Grey dots - Nothing happened to that cell

[1] "Percentage of Ambient RNA (UMI) removed: 17.01 ileum_org_pig-G3_IL1_1-filtered_ref_GTF-incl_intr"

Extensive filtering

Description:
  • By default, we automatically filter out cells with a percentage of MT reads above 10%, with gene and transcript counts below the 2% quantile as a lower limit. No filtering is applied on the higher limit as these cells could represent doublets that we want to classify by DoubletFinder instead of removing them by force. However, if the user has prior knowledge on the dataset, filtering can also be applied by user-defined cutoff values for the number of genes, transcripts and percentage of MT reads. Additionally, the user may also adjust the upper and lower quantiles for the parameters mentioned above. It is important to consider that by removing cell in the upper limit by user-defined cutoff values or quantiles, there is a good chance that true doublets are being removed before identified in an algorithmic fashion.

  • Note that our default parameters have been performing well in high complexity (porcine ileum and colon tissue, with immune) and low complexity data (porcine ileum organoid) without loosing many cell-types (including some rare immune cells with low number of genes/transcripts).

Results:
  • Now take a look in the chunk below… how many cells do you have? Is it significantly lower than before?
    • (The cells are called ‘samples’).
    • (Ignore the inflated number of ‘feautures’. These are the number of genes from two assays in Seurat).
$`ileum_org_pig-G3_IL1_1-filtered_ref_GTF-incl_intr`
An object of class Seurat 
44080 features across 2637 samples within 2 assays 
Active assay: RNA (22040 features, 2500 variable features)
 3 layers present: counts, data, scale.data
 1 other assay present: original.counts
 2 dimensional reductions calculated: pca, umap

Multiplet Removal

Description:
  • The DoubletFinder algorithm first generates artificial doublets by randomly merging different cells from the data. In total, one artificial doublet is generated per four cells. We are essentially creating a new dataset where artificial doublets are added to the mix. By doing so, the artificial doublets resemble droplets that may contain two completely different cell types. Arguably, the same process likely occurs as true doublets form in the microfluidic container. DoubletFinder then carries out PCAs using our previously determined optimal number of PC-dimensions (during the unsupervised clustering step). The PC distance matrix is then used to find artificial K-nearest neighbors to define where the true and the artificial doublets share the same neighborhood. This step is recursive and computational expensive and thus we allow the user to choose the number of CPU-cores (4 cores by default). Once complete, we remove the added artificial doublets and the pre-defined proportion of identified real doublets from the dataset.

  • Since there is a linear relationship between the percentage of true doublets and number of recovered cells for the “Single Cell 3’ Gene Expression Assay”, we implemented this linearity in the algorithm to ensure the model does not over or underestimate the true doublets in the dataset.

  • The relationship between the number of recovered cells and true doublets is provided by 10X (https://kb.10xgenomics.com/hc/en-us/articles/360001378811-What-is-the-maximum-number-of-cells-that-can-be-profiled-). We make a linear regression from this and implement it into DoubletFinder.

  • Please increase the number of cores for this step if have many cells. Finding artificial K-nearest neighbors during the parameter sweep can be computationally expensive. The number of cores should NOT exceed the available resources in your system provided to the pipeline. If you do, then DoubletFinder will likely crash!

Results:
  • Doublet UMAP plot:
    • Representing the identified doublets within the preliminary cluster. Often, the doublets are located on the edges or between other cell population.
  • Violin plots:
    • Representing the scattered distribution of doublets and singlets as a function of gene and transcript counts. Here it is expected that the doublets contain more genes and transcripts when compared to singlets.

ileum_org_pig-G3_IL1_1-filtered_ref_GTF-incl_intr
Doublet Singlet 
     55    2582 

Final filtering and QC plots

Results:
  • In the chuck below, we will do another data filtering by taking out the identified muultiplets in the dataset.
    • Now you have can finally compare your results and number of cells before and after filtering. It gives you an idea how aggressively you have filtered your data.
    • Likewise, you can compare the QC plots to what had before. Do you see any improvement here?
    • Remember that you can always change the parameters to your liking an run it again.
  • It is advised to try to annotate you cells using the pre-processed data and see if you find your expected cells (in the right proportion). If you think that you are missing some rare cells that contain few genes/transcripts, then try to use the raw counts matrix as a starting point. This will likely expose those cells that have been filtered out by Cellrangers 500 UMI threshold. By using the raw matrix, the pipeline will automatically remove all cells that have <100 genes. By doing so, we ensure that you do not end up many low quality droplets. Even the rarest cells usually do not contain less than 100 genes anyway. Feel free to disagree and change the parameter to your liking. If you do not change anything, then the threshold is always set at 100 genes. NEVER TOUCH THIS PARAMETER IF YOU AEE WORKING WITH THE FILTERED COUNTS MATRIX! You will always lose cells that contain few genes/transcripts.
$`ileum_org_pig-G3_IL1_1-filtered_ref_GTF-incl_intr`
An object of class Seurat 
44080 features across 2582 samples within 2 assays 
Active assay: RNA (22040 features, 2500 variable features)
 3 layers present: counts, data, scale.data
 1 other assay present: original.counts
 2 dimensional reductions calculated: pca, umap

`geom_smooth()` using formula = 'y ~ x'
`geom_smooth()` using formula = 'y ~ x'

LS0tCm5hbWU6ICJTb21lIGlycmVsZXZhbnQgZ3V5IGZyb20gZWFydGggZG9pbmcgaGlzIHRoZXNpcyIKdGl0bGU6ICJTaW5nbGUgY2VsbC9udWNsZWkgUUMgYW5kIHByZS1wcm9jZXNzaW5nIgpkYXRlOiAiYHIgZm9ybWF0KFN5cy50aW1lKCksICclZCAlQiwgJVknKWAiCm91dHB1dDogaHRtbF9ub3RlYm9vawotLS0KICAgICAgICAgICAgYGBge3IsIGVjaG89RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CgojIyMjIyMjIyBzbmFrZW1ha2UgcHJlYW1ibGUgc3RhcnQgKGF1dG9tYXRpY2FsbHkgaW5zZXJ0ZWQsIGRvIG5vdCBlZGl0KSAjIyMjIyMjIwpsaWJyYXJ5KG1ldGhvZHMpClNuYWtlbWFrZSA8LSBzZXRDbGFzcygKICAgICJTbmFrZW1ha2UiLAogICAgc2xvdHMgPSBjKAogICAgICAgIGlucHV0ID0gImxpc3QiLAogICAgICAgIG91dHB1dCA9ICJsaXN0IiwKICAgICAgICBwYXJhbXMgPSAibGlzdCIsCiAgICAgICAgd2lsZGNhcmRzID0gImxpc3QiLAogICAgICAgIHRocmVhZHMgPSAibnVtZXJpYyIsCiAgICAgICAgbG9nID0gImxpc3QiLAogICAgICAgIHJlc291cmNlcyA9ICJsaXN0IiwKICAgICAgICBjb25maWcgPSAibGlzdCIsCiAgICAgICAgcnVsZSA9ICJjaGFyYWN0ZXIiLAogICAgICAgIGJlbmNoX2l0ZXJhdGlvbiA9ICJudW1lcmljIiwKICAgICAgICBzY3JpcHRkaXIgPSAiY2hhcmFjdGVyIiwKICAgICAgICBzb3VyY2UgPSAiZnVuY3Rpb24iCiAgICApCikKc25ha2VtYWtlIDwtIFNuYWtlbWFrZSgKICAgIGlucHV0ID0gbGlzdCgnL2hvbWUvb3V0cHV0X3Rlc3QyJyksCiAgICBvdXRwdXQgPSBsaXN0KCcvaG9tZS9vdXRwdXRfdGVzdDIvaWxldW1fb3JnX3BpZy1HM19JTDFfMS1maWx0ZXJlZF9yZWZfR1RGLWluY2xfaW50ci9zY1JOQS5uYi5odG1sJyksCiAgICBwYXJhbXMgPSBsaXN0KCcvaG9tZS9vdXRwdXRfdGVzdDInLCAnaWxldW1fb3JnX3BpZy1HM19JTDFfMS1maWx0ZXJlZF9yZWZfR1RGLWluY2xfaW50cicsICdvdXRzL2ZpbHRlcmVkX2ZlYXR1cmVfYmNfbWF0cml4JywgJ291dHMvcmF3X2ZlYXR1cmVfYmNfbWF0cml4JywgJ2lsZXVtX29yZ19waWctRzNfSUwxXzEtZmlsdGVyZWRfcmVmX0dURi1pbmNsX2ludHInLCAnU3VzIHNjcm9mYScsICcnLCAnJywgJycsICcnLCAnJywgJycsICcyJywgJzInLCAnL2hvbWUvcGlwZWxpbmUvYmFja3VwL21hcmtlcnMvZ2VuZS50eHQnLCAnJywgJycsICcnLCAnJywgJycsICcnLCAnJywgJycsICcnLCAnNCcsICcnLCAnL2hvbWUvb3V0cHV0X3Rlc3QyL2lsZXVtX29yZ19waWctRzNfSUwxXzEtZmlsdGVyZWRfcmVmX0dURi1pbmNsX2ludHInLCAicGFyZW50X2RpciIgPSAnL2hvbWUvb3V0cHV0X3Rlc3QyJywgInNhbXBsZV9uYW1lcyIgPSAnaWxldW1fb3JnX3BpZy1HM19JTDFfMS1maWx0ZXJlZF9yZWZfR1RGLWluY2xfaW50cicsICJjb3VudHNfcGF0aF9maWx0ZXJlZCIgPSAnb3V0cy9maWx0ZXJlZF9mZWF0dXJlX2JjX21hdHJpeCcsICJjb3VudHNfcGF0aF9yYXciID0gJ291dHMvcmF3X2ZlYXR1cmVfYmNfbWF0cml4JywgImdyYXBoX25hbWVzIiA9ICdpbGV1bV9vcmdfcGlnLUczX0lMMV8xLWZpbHRlcmVkX3JlZl9HVEYtaW5jbF9pbnRyJywgImFuaW1hbCIgPSAnU3VzIHNjcm9mYScsICJ1c2VfcmF3X29ubHkiID0gJycsICJNSU5fY2VsbCIgPSAnJywgIk1JTl9mZWF0dXJlIiA9ICcnLCAibmZlYXR1cmVzIiA9ICcnLCAidW1hcF9yZXNvbHV0aW9uIiA9ICcnLCAibG93X2NvbXBsZXhpdHkiID0gJycsICJuX2hpZ2hseV9hZmZlY3RlZF9nZW5lcyIgPSAnMicsICJuX21hcmtlcnNfZ2VuZXMiID0gJzInLCAiY2Fub25pY2FsX21hcmtlcnMiID0gJy9ob21lL3BpcGVsaW5lL2JhY2t1cC9tYXJrZXJzL2dlbmUudHh0JywgImZlYXR1cmVfTE9XIiA9ICcnLCAiY291bnRfTE9XIiA9ICcnLCAiZmVhdHVyZV9ISUdIIiA9ICcnLCAiY291bnRfSElHSCIgPSAnJywgIm10X0NvbiIgPSAnJywgImZlYXR1cmVfcXVhbnRpbGVfbG93IiA9ICcnLCAiVU1JX3F1YW50aWxlX2xvdyIgPSAnJywgImZlYXR1cmVfcXVhbnRpbGVfaGlnaCIgPSAnJywgIlVNSV9xdWFudGlsZV9oaWdoIiA9ICcnLCAiQ1BVX2NvcmVzIiA9ICc0JywgInNraXBfRG91YmxldEZpbmRlciIgPSAnJywgImtuaXRzIiA9ICcvaG9tZS9vdXRwdXRfdGVzdDIvaWxldW1fb3JnX3BpZy1HM19JTDFfMS1maWx0ZXJlZF9yZWZfR1RGLWluY2xfaW50cicpLAogICAgd2lsZGNhcmRzID0gbGlzdCgnL2hvbWUvb3V0cHV0X3Rlc3QyJywgJ2lsZXVtX29yZ19waWctRzNfSUwxXzEtZmlsdGVyZWRfcmVmX0dURi1pbmNsX2ludHInLCAib3V0c19kaXIiID0gJy9ob21lL291dHB1dF90ZXN0MicsICJzYW1wbGVzIiA9ICdpbGV1bV9vcmdfcGlnLUczX0lMMV8xLWZpbHRlcmVkX3JlZl9HVEYtaW5jbF9pbnRyJyksCiAgICB0aHJlYWRzID0gMSwKICAgIGxvZyA9IGxpc3QoKSwKICAgIHJlc291cmNlcyA9IGxpc3QoJ3RtcGRpcicsICJ0bXBkaXIiID0gJy90bXAnKSwKICAgIGNvbmZpZyA9IGxpc3QoIm91dF9kaXJlY3RvcnkiID0gJycsICJyZWFkc19kaXJlY3RvcnkiID0gJycsICJzYW1wbGVfbmFtZXMiID0gJy9ob21lL291dHB1dF90ZXN0MicsICJjZWxscmFuZ2VyX2RpcmVjdG9yeSIgPSAnJywgInRyYW5zY3JpcHRvbWVfZGlyZWN0b3J5IiA9ICcnLCAibWFrZV9uZXdfcmVmIiA9ICcnLCAiZWRpdF9ndGYiID0gJycsICJndGZfZGlyZWN0b3J5IiA9ICcnLCAiZmFzdGFfZGlyZWN0b3J5IiA9ICcnLCAiZ2VuZV9iaW90eXBlIiA9ICdnZW5lX2Jpb3R5cGU6cHJvdGVpbl9jb2RpbmcnLCAiY2VsbHJhbmdlcl9jb3VudHNfb3B0aW9ucyIgPSAnJywgImFuaW1hbCIgPSAnU3VzIHNjcm9mYScsICJ1c2UucmF3Lm9ubHkiID0gJycsICJtaW4uY2VsbCIgPSAnJywgIm1pbi5mZWF0dXJlIiA9ICcnLCAibmZlYXR1cmVzIiA9ICcnLCAidW1hcC5yZXNvbHV0aW9uIiA9ICcnLCAibG93LmNvbXBsZXhpdHkiID0gJycsICJuLmhpZ2hseV9hZmZlY3RlZC5nZW5lcyIgPSAnMicsICJuLm1hcmtlcnMuZ2VuZXMiID0gJzInLCAiZmVhdHVyZUxPVyIgPSAnJywgImNvdW50TE9XIiA9ICcnLCAiZmVhdHVyZUhJR0giID0gJycsICJjb3VudEhJR0giID0gJycsICJtdC5Db24iID0gJycsICJmZWF0dXJlLnF1YW50aWxlLmxvdyIgPSAnJywgIlVNSS5xdWFudGlsZS5sb3ciID0gJycsICJmZWF0dXJlLnF1YW50aWxlLmhpZ2giID0gJycsICJVTUkucXVhbnRpbGUuaGlnaCIgPSAnJywgInNraXAuRG91YmxldEZpbmRlciIgPSAnJywgIkNQVS5jb3JlcyIgPSAnNCcpLAogICAgcnVsZSA9ICdRQ19hbmRfUHJlX3Byb2Nlc3NpbmcnLAogICAgYmVuY2hfaXRlcmF0aW9uID0gYXMubnVtZXJpYyhOQSksCiAgICBzY3JpcHRkaXIgPSAnL2hvbWUvcGlwZWxpbmUvYmFja3VwL3NjcmlwdCcsCiAgICBzb3VyY2UgPSBmdW5jdGlvbiguLi4pewogICAgICAgIHdkIDwtIGdldHdkKCkKICAgICAgICBzZXR3ZChzbmFrZW1ha2VAc2NyaXB0ZGlyKQogICAgICAgIHNvdXJjZSguLi4pCiAgICAgICAgc2V0d2Qod2QpCiAgICB9CikKCiMjIyMjIyMjIHNuYWtlbWFrZSBwcmVhbWJsZSBlbmQgIyMjIyMjIyMjCgogICAgICAgICAgICBgYGAKCgpgYGB7ciBMb2FkIExpYnJhcmllcywgZWNobz1GQUxTRSwgcmVzdWx0cz0naGlkZScsIGluY2x1ZGU9RkFMU0V9CmxpYnJhcnkoU2V1cmF0KSAKbGlicmFyeShkcGx5cikKbGlicmFyeShkYnBseXIpIApsaWJyYXJ5KHBhdGNod29yaykKbGlicmFyeSh0aWR5dmVyc2UpCmxpYnJhcnkoZ3N1YmZuKSAKbGlicmFyeShnZ3Bsb3QyKQpsaWJyYXJ5KFJDb2xvckJyZXdlcikKCmxpYnJhcnkoU291cFgpICAgCmxpYnJhcnkoRG91YmxldEZpbmRlcikKCmxpYnJhcnkoQW5ub3RhdGlvbkh1YikKbGlicmFyeShCaW9jRmlsZUNhY2hlKQpsaWJyYXJ5KGVuc2VtYmxkYikgIApsaWJyYXJ5KERyb3BsZXRVdGlscykgCgpsaWJyYXJ5KGtuaXRyKSAKYGBgCgpgYGB7ciBpbXBvcnQgdGhlIHJlcXVpcmVtZW50cywgZWNobz1GQUxTRSwgcmVzdWx0cz0naGlkZScsIGluY2x1ZGU9RkFMU0V9CiMjIyMjIyMjIyMjIyMjIyMjIyMjIENodW5rICMjIyMjIyMjIyMjIyMjIyMjIyMjIAojIC8vIFRoaXMgY2h1bmsgd2Ugc3BlY2lmeSB0aGUgcGF0aHMsIHBhcmFtZXRlcnMsIG5hbWVzIGFuZCBhbGwgZGVwZW5kZW5jaWVzCiMgLy8gVGhlIHB1cnBvc2UgaGVyZSBpcyB0byBzcGVjaWZ5IHRoZSBwYXJhbWV0ZXJzIHdpdGhvdXQgdGhlIHVzZSBvZiBTbmFrZW1ha2UgKGZvciBkZWJ1Z2dpbmcpCiMjIyMjIyMjIyMjIyMjIyMjIyMjICAgICAgICMjIyMjIyMjIyMjIyMjIyMjIyMjIAoKc2Vzc2lvbkluZm8oKQojIFBhdGggMTBYIG91dHB1dDoKcGFyZW50X2RpcmVjdG9yeSA9IHNuYWtlbWFrZUBwYXJhbXMkcGFyZW50X2RpcgoKc2FtcGxlX3BhdGggPSBjKHNuYWtlbWFrZUBwYXJhbXMkc2FtcGxlX25hbWVzKSAjIHNhbXBsZSBmb2xkZXIKY291bnRzX3BhdGhfZmlsdGVyZWQgPSBzbmFrZW1ha2VAcGFyYW1zJGNvdW50c19wYXRoX2ZpbHRlcmVkICMgb3V0cy9maWx0ZXJlZF9mZWF0dXJlX2JjX21hdHJpeApjb3VudHNfcGF0aF9yYXcgPSBzbmFrZW1ha2VAcGFyYW1zJGNvdW50c19wYXRoX3JhdyAjIG91dHMvcmF3X2ZlYXR1cmVfYmNfbWF0cml4CgojIFNhbXBsZSBhbmQgcHJvamVjdCBuYW1lczoKc2FtcGxlX25hbWVzID0gYyhzbmFrZW1ha2VAcGFyYW1zJGdyYXBoX25hbWVzKSAjIFNhbXBsZSBuYW1lLCBmb3IgZ3JhcGhzLCAKCiMgQW5pbWFsIG5hbWVzIEVuc2VtYmw6CmFuaW1hbCA9IHNuYWtlbWFrZUBwYXJhbXMkYW5pbWFsICMgRm9yIEFubm90YXRpb25IdWIncyBxdWVyeSgpIGZ1bmN0aW9uCgojIFVzZSByYXc6IAp1c2UucmF3Lm9ubHkgPSBzbmFrZW1ha2VAcGFyYW1zJHVzZV9yYXdfb25seSAjIHVzZSByYXcgbWF0cml4IG9ubHkgaWYgc3BlY2lmaWVkIAojIEluaXRpYWwgZmlsdGVyaW5nOgptaW4uY2VsbCA9IHNuYWtlbWFrZUBwYXJhbXMkTUlOX2NlbGwKbWluLmZlYXR1cmUgPSBzbmFrZW1ha2VAcGFyYW1zJE1JTl9mZWF0dXJlICMgaWYgdXNpbmcgcmF3IG1hdHJpeCBvbmx5LCB0aGVuIHVzZSB0aGlzIHBhcmFtZXRlciAoc2V0IGl0IGF0IGFyb3VuZCAxMDApCgojIG4gaGlnaGx5IHZhcmlhYmxlIGZlYXR1cmVzCm5mZWF0dXJlcyA9IHNuYWtlbWFrZUBwYXJhbXMkbmZlYXR1cmVzCgojIFVNQVAgcmVzb2x1dGlvbgp1bWFwLnJlc29sdXRpb24gPSBzbmFrZW1ha2VAcGFyYW1zJHVtYXBfcmVzb2x1dGlvbgoKIyBGb3IgU291cFg6Cmxvdy5jb21wbGV4aXR5ID0gc25ha2VtYWtlQHBhcmFtcyRsb3dfY29tcGxleGl0eSAjICJ5ZXMiLCBubyBieSBkZWZhdWx0LCBza2lwIHNvdXBYIHdoZW4gbG93IGNvbXBsZXhpdHkKbi5oaWdobHlfYWZmZWN0ZWQuZ2VuZXMgPSBzbmFrZW1ha2VAcGFyYW1zJG5faGlnaGx5X2FmZmVjdGVkX2dlbmVzCm4ubWFya2Vycy5nZW5lcyA9IHNuYWtlbWFrZUBwYXJhbXMkbl9tYXJrZXJzX2dlbmVzCiNjYW5vbmljYWxfbWFya2VycyA9IGMoc25ha2VtYWtlQHBhcmFtcyRjYW5vbmljYWxfbWFya2VycykKY2Fub25pY2FsX21hcmtlcnMgPSBzY2FuKHNuYWtlbWFrZUBwYXJhbXMkY2Fub25pY2FsX21hcmtlcnMsIGNoYXJhY3RlcigpLCBxdW90ZSA9ICIiKSAjIGZyb20gLnR4dAoKIyBFeHRlbnNpdmUgZmlsdGVyaW5nOgpmZWF0dXJlTE9XID0gc25ha2VtYWtlQHBhcmFtcyRmZWF0dXJlX0xPVwpjb3VudExPVyA9IHNuYWtlbWFrZUBwYXJhbXMkY291bnRfTE9XIApmZWF0dXJlSElHSCA9IHNuYWtlbWFrZUBwYXJhbXMkZmVhdHVyZV9ISUdICmNvdW50SElHSCA9IHNuYWtlbWFrZUBwYXJhbXMkY291bnRfSElHSAptdC5Db24gPSBzbmFrZW1ha2VAcGFyYW1zJG10X0NvbgojIEJ5IHF1YW50aWxlCmZlYXR1cmUucXVhbnRpbGUubG93ID0gc25ha2VtYWtlQHBhcmFtcyRmZWF0dXJlX3F1YW50aWxlX2xvdwpVTUkucXVhbnRpbGUubG93ID0gc25ha2VtYWtlQHBhcmFtcyRVTUlfcXVhbnRpbGVfbG93CmZlYXR1cmUucXVhbnRpbGUuaGlnaCA9IHNuYWtlbWFrZUBwYXJhbXMkZmVhdHVyZV9xdWFudGlsZV9oaWdoClVNSS5xdWFudGlsZS5oaWdoID0gc25ha2VtYWtlQHBhcmFtcyRVTUlfcXVhbnRpbGVfaGlnaAoKIyBEb3VibGV0RmluZGVyOgpDUFUuY29yZXMgPSBzbmFrZW1ha2VAcGFyYW1zJENQVV9jb3Jlcwpza2lwLkRvdWJsZXRGaW5kZXIgPSBzbmFrZW1ha2VAcGFyYW1zJHNraXBfRG91YmxldEZpbmRlciAjICJ5ZXMiIG5vIGJ5IGRlZmF1bHQsIHNraXAgRG91YmxldEZpbmRlciB3aGVuIGxvdyBjb21wbGV4aXR5CgpFeHBlcmltZW50YWwgPSAiIiAjIEFjY291bnRzIGZvciB0aGUgYmlvbG9neSAKCiMgUGFyYW1ldGVyIHJ1bGVzCiMgSWYgd2UgdXNlIHJhdyBvbmx5IGJ5IHVzZXIgZGVmaW5pdGlvbiBvciBvbmx5IGF2YWlsYWJsZSByYXcgbWF0cml4IAppZiAoKChzdHJfbGVuZ3RoKGNvdW50c19wYXRoX2ZpbHRlcmVkKSA9PSAwKSB8ICh1c2UucmF3Lm9ubHkgPT0gInllcyIgJiBzdHJfbGVuZ3RoKHVzZS5yYXcub25seSkgIT0gMCkpICYgbWluLmZlYXR1cmUgPT0gIiIpIHsKICBtaW4uZmVhdHVyZSA9ICIxMDAiIH0gZWxzZSB7bWluLmZlYXR1cmUgPSBtaW4uZmVhdHVyZX0KIyBJZiB0aGUgdXNlciBjaGFuZ2VzIHRoZSBVTUFQIHJlc29sdXRpb24KaWYgKHVtYXAucmVzb2x1dGlvbiA9PSAiIiAmIHN0cl9sZW5ndGgodW1hcC5yZXNvbHV0aW9uKSA9PSAwKSB7CiAgdW1hcC5yZXNvbHV0aW9uID0gIjAuOCIgfSBlbHNlIHt1bWFwLnJlc29sdXRpb24gPSB1bWFwLnJlc29sdXRpb259CiMgSWYgdGhlIHVzZXIgc2VsZWN0cyBtaW4uY2VsbCwgdGhlIHNvdXBYIHdpbGwgbm90IHJ1bjoKaWYgKHN0cl9sZW5ndGgobWluLmNlbGwpID4gMCkgewogIGxvdy5jb21wbGV4aXR5ID0gInllcyJ9IGVsc2Uge2xvdy5jb21wbGV4aXR5ID0gbG93LmNvbXBsZXhpdHkKICB9CgoKIyBDb252ZXJ0IHRvIG51bWVyaWMgdmFsdWVzCnVtYXAucmVzb2x1dGlvbiA8LSBhcy5udW1lcmljKHVtYXAucmVzb2x1dGlvbikKbmZlYXR1cmVzIDwtIGFzLm51bWVyaWMobmZlYXR1cmVzKQpuLmhpZ2hseV9hZmZlY3RlZC5nZW5lcyA8LSBhcy5udW1lcmljKG4uaGlnaGx5X2FmZmVjdGVkLmdlbmVzKQpuLm1hcmtlcnMuZ2VuZXMgPC0gYXMubnVtZXJpYyhuLm1hcmtlcnMuZ2VuZXMpCmZlYXR1cmVMT1cgPC0gYXMubnVtZXJpYyhmZWF0dXJlTE9XKQpjb3VudExPVyA8LSBhcy5udW1lcmljKGNvdW50TE9XKQpmZWF0dXJlSElHSCA8LSBhcy5udW1lcmljKGZlYXR1cmVISUdIKQpjb3VudEhJR0ggPC0gYXMubnVtZXJpYyhjb3VudEhJR0gpCm10LkNvbiA8LSBhcy5udW1lcmljKG10LkNvbikKQ1BVLmNvcmVzIDwtIGFzLm51bWVyaWMoQ1BVLmNvcmVzKQpmZWF0dXJlLnF1YW50aWxlLmxvdyA8LSBhcy5udW1lcmljKGZlYXR1cmUucXVhbnRpbGUubG93KSAvIDEwMApVTUkucXVhbnRpbGUubG93IDwtIGFzLm51bWVyaWMoVU1JLnF1YW50aWxlLmxvdykgLyAxMDAKZmVhdHVyZS5xdWFudGlsZS5oaWdoIDwtIGFzLm51bWVyaWMoZmVhdHVyZS5xdWFudGlsZS5oaWdoKSAvIDEwMApVTUkucXVhbnRpbGUuaGlnaCA8LSBhcy5udW1lcmljKFVNSS5xdWFudGlsZS5oaWdoKSAvIDEwMAptaW4uY2VsbCA8LSBhcy5udW1lcmljKG1pbi5jZWxsKQptaW4uZmVhdHVyZSA8LSBhcy5udW1lcmljKG1pbi5mZWF0dXJlKQoKCiMgb3V0cHV0IGtuaXQKb3B0c19rbml0JHNldChyb290LmRpciA9IHNuYWtlbWFrZUBwYXJhbXMka25pdHMpCmBgYAoKYGBge3IgcHJlcGFyZSB0aGUgTVQgZ2VuZXMsIGVjaG89RkFMU0UsIHJlc3VsdHM9J2hpZGUnLCBpbmNsdWRlPUZBTFNFfQojIyMjIyMjIyMjIyMjIyMjIyMjIyBDaHVuayAjIyMjIyMjIyMjIyMjIyMjIyMjIyAKIyAvLyBUaGlzIGNodW5rIGNhbGN1bGF0ZXMgYW5kIHJldHVybnMgYSB2ZWN0b3Igb2YgTWl0b2Nob25kcmlhbCBnZW5lcy4KIyAvLyBUaGUgZ2VuZSBuYW1lcyBmcm9tIG9yZ2FuaXNtIG9mIGludGVyZXN0IGFyZSBpbXBvcnRlZCBmcm9tIEFubm90YXRpb25IdWIKIyMjIyMjIyMjIyMjIyMjIyMjIyMgICAgICAgIyMjIyMjIyMjIyMjIyMjIyMjIyMgCgojIExvYWQgbWl0b2Nob25kcmlhbCBnZW5lcyAocHJvdGVpbiBjb2RpbmcpIAphbm4uaHViIDwtIEFubm90YXRpb25IdWIoYXNrID0gRkFMU0UsIGxvY2FsSHViID0gRkFMU0UpICMgY29ubmVjdCB0byBBbm5odWIKIyBBY2Nlc3MgdGhlIEVuc2VtYmwgZGF0YWJhc2UgZm9yIHBpZwphbm4uaHViLmRhdGFiYXNlIDwtIHF1ZXJ5KGFubi5odWIsIHBhdHRlcm4gPSBjKHBhc3RlKGFuaW1hbCksICJFbnNEYiIpLCBpZ25vcmUuY2FzZSA9IFRSVUUpCiMgQWNxdWlyZSB0aGUgbGF0ZXN0IGFubm90YXRpb24gZmlsZXMKaWQgPC0gYW5uLmh1Yi5kYXRhYmFzZSAlPiUKICAgICAgICBtY29scygpICU+JQogICAgICAgIHJvd25hbWVzKCkgJT4lCiAgICAgICAgdGFpbChuID0gMSkKIyBEb3dubG9hZGluZyB0aGUgRW5zZW1ibGRiIGRhdGFiYXNlCmVuc2VtYmwuZGF0YWJhc2UgPC0gYW5uLmh1YltbaWRdXQojIEV4dHJhY3QgZ2VuZS1sZXZlbCBpbmZvcm1hdGlvbiBmcm9tIHRoZSBkYXRhYmFzZQphbm5vdGF0aW9uc19NVCA8LSBnZW5lcyhlbnNlbWJsLmRhdGFiYXNlLCAKICAgICAgICAgICAgICAgICAgICAgcmV0dXJuLnR5cGUgPSAiZGF0YS5mcmFtZSIpCiMgU2VsZWN0IGFubm90YXRpb25zIG9mIGludGVyZXN0CmFubm90YXRpb25zX01UIDwtIGFubm90YXRpb25zX01UICU+JQogICAgICAgIGRwbHlyOjpzZWxlY3QoZ2VuZV9uYW1lLCBzZXFfbmFtZSkKCiMgZmlsdGVyIGRhdGEgc2V0IGFuZCBrZWVwIE1UIHJvd3MKTVRfcm93cyA8LSB3aGljaChhbm5vdGF0aW9uc19NVCRzZXFfbmFtZSA9PSAiTVQiKSAjIGdldCByb3cgbnVtYmVyIG9mIGVsZW1lbnQgIk1UIiBpbnNpZGUKTVRfZ2VuZXMgPC0gYW5ub3RhdGlvbnNfTVQgJT4lIGRwbHlyOjpzbGljZShNVF9yb3dzKSAgIyBHZXQgTVQgZ2VuZXMgYnkgc2xpY2luZyBhbGwgdGhlIHJvd3MgdGhhdCBkbyBub3QgaGF2ZSAiTVQiCk1UX2dlbmVzIDwtIGFzLmNoYXJhY3RlcihNVF9nZW5lcyRnZW5lX25hbWVbTVRfZ2VuZXMkZ2VuZV9uYW1lICE9ICIiXSkgIyByZW1vdmUgZW1wdHkgIiIgdmFsdWVzCiNNVF9nZW5lcyA9IGMoIk5EMSIsICJORDIiLCAiQ09YMSIsICJDT1gyIiwgIkFUUDgiLCAiQVRQNiIsICJDT1gzIiwgIk5EMyIsICJORDRMIiwgIk5ENCIsICJORDUiLCAiTkQ2IiwgIkNZVEIiKQpgYGAKCmBgYHtyIExvYWQgaW4gcmF3IDEwWCBkYXRhLCBlY2hvPUZBTFNFLCByZXN1bHRzPSdoaWRlJywgaW5jbHVkZT1GQUxTRX0KIyMjIyMjIyMjIyMjIyMjIyMjIyMgQ2h1bmsgIyMjIyMjIyMjIyMjIyMjIyMjIyMgCiMgLy8gVGhpcyBjaHVuayBpbXBvcnRzIHRoZSB0aGUgZmlsdGVyZWQgYW5kIHJhdyBjb3VudCBtYXRyaWNlcyBnZW5lcmF0ZWQgYnkgQ2VsbFJhbmdlcgojIC8vIFRoZSBNaXRvY2hvbmRyaWEgZ2VuZXMgd2lsbCBhZGp1c3RlZCBieSBzdWJzdGl0dXRpbmcgYSBzdHJpbmcgb2YgIk1ULSIgdG8gdGhlIGluaXRpYWwgZ2VuZSBuYW1lCiMjIyMjIyMjIyMjIyMjIyMjIyMjICAgICAgICMjIyMjIyMjIyMjIyMjIyMjIyMjIAoKaWYgKHVzZS5yYXcub25seSA9PSAieWVzIiAmIHN0cl9sZW5ndGgodXNlLnJhdy5vbmx5KSAhPSAwKSB7CiAgICAjIElmIHdlIG9ubHkgd2FudCB0byB1c2UgcmF3IGRhdGUsIHRoZW4gcnVuIHRoaXMKICBkMTB4LmRhdGEgPC0gc2FwcGx5KHNhbXBsZV9wYXRoLCBmdW5jdGlvbihpKXsKICBkMTB4IDwtIFJlYWQxMFgoZmlsZS5wYXRoKHBhcmVudF9kaXJlY3RvcnksIGksIHBhc3RlKGNvdW50c19wYXRoX3JhdykpKQogIH0pCiAgZDEweC5kYXRhLnJhdyA8LSBzYXBwbHkoc2FtcGxlX3BhdGgsIGZ1bmN0aW9uKGkpewogIGQxMHggPC0gUmVhZDEwWChmaWxlLnBhdGgocGFyZW50X2RpcmVjdG9yeSwgaSwgcGFzdGUoY291bnRzX3BhdGhfcmF3KSkpICMgYW5kIG1ha2UgYW5vdGhlciBjb3B5IG9mIHRoZSAicmF3X2ZlYXR1cmVfYmNfbWF0cml4LyIgKGZvciBTb3VwWCkKICB9KQp9IGVsc2UgewogIGlmIChzdHJfbGVuZ3RoKGNvdW50c19wYXRoX2ZpbHRlcmVkKSAhPSAwKSB7CiAgIyBMb2FkIHRoZSBmaWx0ZXJlZCBzaW5nbGUgY2VsbCBkYXRhIGZyb20gcGF0aCBpZiBhdmFpbGFibGUKICBkMTB4LmRhdGEgPC0gc2FwcGx5KHNhbXBsZV9wYXRoLCBmdW5jdGlvbihpKXsKICBkMTB4IDwtIFJlYWQxMFgoZmlsZS5wYXRoKHBhcmVudF9kaXJlY3RvcnksIGksIHBhc3RlKGNvdW50c19wYXRoX2ZpbHRlcmVkKSkpIAojICBjb2xuYW1lcyhkMTB4KSA8LSBwYXN0ZShzYXBwbHkoc3Ryc3BsaXQoY29sbmFtZXMoZDEweCksc3BsaXQ9Ii0iKSwnW1snLDFMKSxpLHNlcD0iLSIpCiMgIGQxMHggCiAgfSkKICBpZiAoc3RyX2xlbmd0aChjb3VudHNfcGF0aF9yYXcpICE9IDApIHsKICAgICMgQW5kIGxvYWQgdGhlIHJhdyBzaW5nbGUgY2VsbCBkYXRhIGZyb20gcGF0aCBpZiBhdmFpbGFibGUKICAgIGQxMHguZGF0YS5yYXcgPC0gc2FwcGx5KHNhbXBsZV9wYXRoLCBmdW5jdGlvbihpKXsKICAgIGQxMHggPC0gUmVhZDEwWChmaWxlLnBhdGgocGFyZW50X2RpcmVjdG9yeSwgaSwgcGFzdGUoY291bnRzX3BhdGhfcmF3KSkpCiAgICB9KQogICAgfSBlbHNlIHsKICAgICAgIyBFbHNlIGxvYWQgdGhlIGZpbHRlcmVkIHNpbmdsZSBjZWxsIGRhdGEgZnJvbSBwYXRoIGlmIHJhdyBub3QgYXZhaWxhYmxlCiAgICAgIGQxMHguZGF0YS5yYXcgPC0gc2FwcGx5KHNhbXBsZV9wYXRoLCBmdW5jdGlvbihpKXsKICAgICAgZDEweCA8LSBSZWFkMTBYKGZpbGUucGF0aChwYXJlbnRfZGlyZWN0b3J5LCBpLCBwYXN0ZShjb3VudHNfcGF0aF9maWx0ZXJlZCkpKQogICAgICB9KQogICAgICB9Cn0gZWxzZSB7IAogICMgTG9hZCB0aGUgcmF3IHNpbmdsZSBjZWxsIGRhdGEgZnJvbSBwYXRoIGlmIGZpbHRlcmVkIG5vdCBhdmFpbGFibGUgYXQgYWxsIQogIGQxMHguZGF0YSA8LSBzYXBwbHkoc2FtcGxlX3BhdGgsIGZ1bmN0aW9uKGkpewogIGQxMHggPC0gUmVhZDEwWChmaWxlLnBhdGgocGFyZW50X2RpcmVjdG9yeSwgaSwgcGFzdGUoY291bnRzX3BhdGhfcmF3KSkpCiAgfSkKICBkMTB4LmRhdGEucmF3IDwtIHNhcHBseShzYW1wbGVfcGF0aCwgZnVuY3Rpb24oaSl7CiAgZDEweCA8LSBSZWFkMTBYKGZpbGUucGF0aChwYXJlbnRfZGlyZWN0b3J5LCBpLCBwYXN0ZShjb3VudHNfcGF0aF9yYXcpKSkgIyBhbmQgbWFrZSBhbm90aGVyIGNvcHkgb2YgdGhlICJyYXdfZmVhdHVyZV9iY19tYXRyaXgvIiAoZm9yIFNvdXBYKQogIH0pCiAgfQogIH0KCiMgQWRkIG1pdG9jaG9uZHJpYWwgZ2VuZXMgdG8gZDEweC5kYXRhIG1hdHJpeCBhbmQgcmVtb3ZlIHVuZGVyc2NvcmVzIGZyb20gZ2VuZSBuYW1lcwpmb3IgKGkgaW4gc2FtcGxlX3BhdGgpIHsKICByb3duYW1lcy5kMTB4IDwtIHJvd25hbWVzKGQxMHguZGF0YVtbaV1dKSAjIFNhdmUgcm93IG5hbWVzCiAgTVQucG9zaXRpb25zLmQxMHggPC0gbmEub21pdChjKG1hdGNoKGMocGFzdGUoTVRfZ2VuZXMpKSwgcm93bmFtZXMuZDEweCkpKSAjIEZpbmQgaW5kZXggb2YgbWl0b2Nob25kcmlhbCBnZW5lcyBpbiBzYXZlZCByb3cgbmFtZXMKICAjIFVzZSBpbmRleCBvZiBtaXRvY2hvbmRyaWFsIGdlbmVzIGFuZCByZXBsYWNlIHRob3NlIGdlbmUgbmFtZXMgd2l0aCAiXk1ULSIgKyB0aGUgZ2VuZSBuYW1lIGlmIG5vdCBhbHJlYWR5IHByZXNlbnQKICBpZiAoZ3JlcGwoIk1ULSIsIE1UX2dlbmVzWzFdKSA9PSBUUlVFKSB7CiAgcm93bmFtZXMuZDEweFtNVC5wb3NpdGlvbnMuZDEweF0gPC0gYyhwYXN0ZSgiIiwgTVRfZ2VuZXMsIHNlcCA9ICIiKSkgIyBLZWVwIGFzIGlzIGlmIE1ULQp9IGVsc2UgaWYgKGdyZXBsKCJtdC0iLCBNVF9nZW5lc1sxXSkgPT0gVFJVRSkgewogIHJvd25hbWVzLmQxMHhbTVQucG9zaXRpb25zLmQxMHhdIDwtIGMocGFzdGUoIiIsIE1UX2dlbmVzLCBzZXAgPSAiIikpICMgS2VlcCBhcyBpcyBpZiBtdC0KICB9IGVsc2Ugcm93bmFtZXMuZDEweFtNVC5wb3NpdGlvbnMuZDEweF0gPC0gYyhwYXN0ZSgiTVQtIiwgTVRfZ2VuZXMsIHNlcCA9ICIiKSkgIyBhZGQgTVQtIHRvIGdlbmUgbmFtZQogIHJvdy5uYW1lcyhkMTB4LmRhdGFbW2ldXSkgPC0gcm93bmFtZXMuZDEweCAjIEFwcGVuZCB0aGUgbmV3IHJvdyBuYW1lcyB3aXRoIGNvcnJlY3QgTVQgbWFya3MgaW4gb3JpZ2luYWwgTWF0cml4CiAgcm93Lm5hbWVzKGQxMHguZGF0YVtbaV1dKSA8LSBnc3ViKCJfIiwgIi0iLCByb3duYW1lcyhkMTB4LmRhdGFbW2ldXSkpIAp9CiMgQW5kIGFkZCBtaXRvY2hvbmRyaWFsIGdlbmVzIHRvZCAxMHguZGF0YS5yYXcgbWF0cml4IGFuZCByZW1vdmUgdW5kZXJzY29yZXMgaW4gZ2VuZSBuYW1lcwpmb3IgKGkgaW4gc2FtcGxlX3BhdGgpIHsKICByb3duYW1lcy5kMTB4LnJhdyA8LSByb3duYW1lcyhkMTB4LmRhdGEucmF3W1tpXV0pIAogIE1ULnBvc2l0aW9ucy5kMTB4LnJhdyA8LSBuYS5vbWl0KGMobWF0Y2goYyhwYXN0ZShNVF9nZW5lcykpLCByb3duYW1lcy5kMTB4LnJhdykpKQogIGlmIChncmVwbCgiTVQtIiwgTVRfZ2VuZXNbMV0pID09IFRSVUUpIHsKICByb3duYW1lcy5kMTB4LnJhd1tNVC5wb3NpdGlvbnMuZDEweC5yYXddIDwtIGMocGFzdGUoIiIsIE1UX2dlbmVzLCBzZXAgPSAiIikpICMgS2VlcCBhcyBpcyBpZiBNVC0KfSBlbHNlIGlmIChncmVwbCgibXQtIiwgTVRfZ2VuZXNbMV0pID09IFRSVUUpIHsKICByb3duYW1lcy5kMTB4LnJhd1tNVC5wb3NpdGlvbnMuZDEweC5yYXddIDwtIGMocGFzdGUoIiIsIE1UX2dlbmVzLCBzZXAgPSAiIikpICMgS2VlcCBhcyBpcyBpZiBtdC0KICB9IGVsc2Ugcm93bmFtZXMuZDEweC5yYXdbTVQucG9zaXRpb25zLmQxMHgucmF3XSA8LSBjKHBhc3RlKCJNVC0iLCBNVF9nZW5lcywgc2VwID0gIiIpKSAjIGFkZCBNVC0gdG8gZ2VuZSBuYW1lCiAgcm93Lm5hbWVzKGQxMHguZGF0YS5yYXdbW2ldXSkgPC0gcm93bmFtZXMuZDEweC5yYXcKICByb3cubmFtZXMoZDEweC5kYXRhLnJhd1tbaV1dKSA8LSBnc3ViKCJfIiwgIi0iLCByb3duYW1lcyhkMTB4LmRhdGEucmF3W1tpXV0pKQp9CmBgYAoKIyMjIyBJbiB0aGUgY2h1Y2sgYmVsb3csIHdlIHdpbGwgbWFrZSBTZXVyYXQgb2JqZWN0cyBvZiBhbGwgc2FtcGxlcyAoYW5kIGFwcGx5IGJhc2ljIGZpbHRlcmluZyBiYXNlZCBvbiBhYnNvbHV0ZSBtZWRpYW4gZGV2aWF0aW9uIHRvIHJlbW92ZSBvdXRsaWVycyk6ICMjIyMKCiMjIyMjIERlc2NyaXB0aW9uOiAjIyMjIwoKKiBGb3IgZWFjaCBvYmplY3QsIHdlIGtlZXAgYWxsIGdlbmVzIHRoYXQgYXJlIGV4cHJlc3NlZCBpbiBhdCBsZWFzdCAwIGNlbGxzLCB0aHVzIHdlIGtlZXAgYWxsIGdlbmVzIGFzIHRoaXMgaXMgcmVxdWlyZWQgZm9yIHRoZSByZW1vdmFsIG9mIGFtYmllbnQgUk5BIChUaGUgQ2VsbHJhbmdlIGZpbHRlcmVkX2ZlYXR1cmVfYmNfbWF0cml4IGRvZXMgbm90IGNvbnRhaW4gZ2VuZXMgdGhhdCBoYXZlIG5vIGV4cHJlc3Npb24gYWNyb3NzIGFsbCBjZWxscywgYnV0IHRoaXMgaXMgb2Z0ZW4gbm90IHRoZSBjYXNlIGZvciB0aGUgcmF3X2ZlYXR1cmVfYmNfbWF0cml4LCBhbmQgY29uc2lkZXJpbmcgdGhhdCBib3RoIG1hdHJpY2VzIHdpbGwgYmUgdXNlZCBmb3IgdGhlIGRldGVjdGlvbiBvZiBhbWJpZW50IFJOQSBpdCBpcyBub3Qgd2lzZSB0byBmaWx0ZXIgZ2VuZXMgd2l0aCAwIGNvdW50cyBpbiB0aGUgZmlsdGVyZWRfZmVhdHVyZV9iY19tYXRyaXguIEhvd2V2ZXIsIHRoaXMgaXMgbm90IGFuIGlzc3VlIGlmIHRoZSB1c2VyIGNob29zZXMgdG8gd29yayB3aXRoIHRoZSBmaWx0ZXJlZF9mZWF0dXJlX2JjX21hdHJpeCB3aXRob3V0IGluY2x1ZGluZyB0aGUgcmF3X2ZlYXR1cmVfYmNfbWF0cml4ZnJvbSBmcm9tIHRoZSB0aGUgc3RhcnQpLgoqIFNpbWlsYXJseSwgZm9yIG5vdyB3ZSB3YW50IHRvIGtlZXAgYWxsIGNlbGxzIHRoYXQgaGF2ZSBhdCBsZWFzdCAwIGdlbmVzIGV4cHJlc3NlZC4gV2Ugd2lsbCBsYXRlciBmaWx0ZXIgb3V0IGFsbCBjZWxscyB0aGF0IGhhdmUgbm90IGF0IGxlYXN0IHgtbnVtYmVyIG9mIGdlbmVzIGV4cHJlc3NlZCBhZnRlciBzdWNjZXNzZnVsbHkgcmVtb3ZpbmcgYW1iaWVudCBSTkEuIEtlZXAgaW4gbWluZCB0aGF0IGluIHJlYWxpdHkgbm8gY2VsbHMgd2lsbCBiZSBmb3VuZCB3aXRoIDAgZ2VuZXMgZXhwcmVzc2VkIGFueXdheSBjb25zaWRlcmluZyB0aGUgQ2VsbHJhbmdlciBwaXBlbGluZSBhbHJlYWR5IHJlbW92ZWQgZW1wdHkgZHJvcGxldHMgYW5kIGNlbGxzIGNvbnRhaW5pbmcgPDUwMCBVTUlzLgpIb3dldmVyLCBpZiB5b3UgY2hvb3NlIHRvIHdvcmsgd2l0aCB0aGUgcmF3X2ZlYXR1cmVfYmNfbWF0cml4LCB5b3UgY2FuIGFjdHVhbGx5IGZpc2ggb3V0IGNlbGwgdGhhdCBtYXkgdHJ1bHkgaGF2ZSA8MTAwIGdlbmVzIGFuZCA8NTAwIFVNSXMuIEluIHRoYXQgY2FzZSwgd2Ugd2lsbCBtYWtlIHN1cmUgdGhhdCB3ZSByZW1vdmUgZHJvcGxldHMgKGNlbGxzKSB0aGF0IGhhdmUgPDEwMCBnZW5lcyBieSBkZWZhdWx0LiBZb3UgY2FuIGNob29zZSB0byBjaGFuZ2UgdGhpcyBwYXJhbWV0ZXIsIGJ1dCBpdCBpcyB2ZXJ5IHVubGlrZWx5IHRvIGZpbmQgcmVhbCBjZWxscyB3aXRoIDwxMDAgZ2VuZXMuIAoKIyMjIyMgUmVzdWx0czogIyMjIyMKCiogRnJvbSBub3cgb24geW91ICh0aGUgdXNlcikgc2hvdWxkIGtlZXAgYW4gZXllIG9uIHRoZSAidGhlIG51bWJlciBvZiBzYW1wbGVzIChjZWxscykiIGluIHRoZSBjaHVjayBiZWxvdy4gVGhlIG51bWJlciBvZiBzYW1wbGVzIGluIGVhY2ggZmlsdGVyaW5nIHN0ZXAgd2lsbCBnaXZlIHlvdSBhbiBpZGVhIGhvdyBtYW55IGNlbGwgeW91IGFyZSBsb3NpbmcgaW4gZWFjaCBzdGVwLgpgYGB7ciBjb252ZXJ0aW5nIDEwWCBkYXRhIGludG8gU2V1cmF0IG9iamVjdHMsIGVjaG89RkFMU0V9CiMjIyMjIyMjIyMjIyMjIyMjIyMjIENodW5rICMjIyMjIyMjIyMjIyMjIyMjIyMjIAojIC8vIFRoaXMgY2h1bmsgaW1wb3J0cyB0aGUgbW9kaWZpZWQgZmlsdGVyZWRfZmVhdHVyZV9iY19tYXRyaXggYW5kIGNvbnZlcnRzIG90IHRvIGEgU2V1cmF0IG9iamVjdAojIC8vIFRoZSBTZXVyYXQgb2JqZWN0IHN0b3JlcyB0aGUgY291bnQgbWF0cmljZXMgaW4gc2xvdHMgCiMgLy8gQW55IG1vZGlmaWNhdGlvbiB0byB0aGUgY291bnQgbWF0cml4IHdpbGwgYXV0b21hdGljYWxseSBhZGQgaXQgdG8gYSBuZXcgc2xvdCAoZS5nLiBzY2FsaW5nIG9yIG5vcm1hbGl6YXRpb24pCiMgLy8gVGhpcyBjaHVuayBhbHNvIGNvbnRhaW5zIGEgZnVuY3Rpb24gdG8gY2FsY3VsYXRlIHRoZSBwZXJjZW50YWdlIG9mIGV4cGVjdGVkIGRyb3BsZXRzIGNvbnRhaW5pbmcgbW9yZSB0aGFuIG9uZSBjZWxsCiMjIyMjIyMjIyMjIyMjIyMjIyMjICAgICAgICMjIyMjIyMjIyMjIyMjIyMjIyMjIAoKIyBNYWtpbmcgU2V1cmF0IG9iamVjdHMgYW5kIHB1dHRpbmcgdGhlbSBpbiBhIHZlY3Rvcgpzb2JqX2xpc3QgPC0gbGlzdCgpICMgbWFrZSBlbXB0eSBsaXN0IHRvIGFwcGVuZCBTZXVyYXQgT2JqZWN0cyBpbiB0aGUgbG9vcCBiZWxvdwpmb3IgKGkgaW4gMTpsZW5ndGgoeCA9IHNhbXBsZV9wYXRoKSkgeyAgIyB3ZSBsb29wIGluIHJhbmdlIG9mIHNhbXBsZV9uYW1lLCBiZWNhdXNlIHRoYXQgZGV0ZXJtaW5lIHRoZSBudW1iZXIgb2YgcmVwbGljYXRlcyB3ZSBoYXZlCiAgbmFtZSA8LSBwYXN0ZSgnJywgc2FtcGxlX3BhdGhbaV0sIHNlcD0nJykgIyBuYW1lIHRoZSBvYmplY3RzIGluIGxpc3QKICBzb2JqX2xpc3RbbmFtZV0gPC0gbGlzdChDcmVhdGVTZXVyYXRPYmplY3QoY291bnRzID0gZDEweC5kYXRhW1tpXV0sIHByb2plY3QgPSBwYXN0ZShzYW1wbGVfbmFtZXNbaV0pLCBtaW4uY2VsbHMgPSBpZiAobWluLmNlbGwgPj0gMCAmIGlzLm5hKG1pbi5jZWxsKSA9PSBGQUxTRSl7CiAgICBtaW4uY2VsbCA9IG1pbi5jZWxsfWVsc2V7bWluLmNlbGwgPSAwfSwgbWluLmZlYXR1cmVzID0gaWYgKG1pbi5mZWF0dXJlID49IDAgJiBpcy5uYShtaW4uZmVhdHVyZSkgPT0gRkFMU0UpewogICAgICBtaW4uZmVhdHVyZSA9IG1pbi5mZWF0dXJlfWVsc2V7bWluLmZlYXR1cmUgPSAwfSkpICMgYXBwZW5kIHRoZSBTZXVyYXQgb2JqZWN0cyBpbiBhIGxpc3Qgb2YgU2V1cmF0IE9iamVjdHMKIyAgICBwcmludChzb2JqX2xpc3QpICMgQVNTRVJUIENPREUgKFJFT01WRSBMQVRFUiEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhKQp9CgojIyMjIyMjIyMjIEZ1bmN0aW9uICMjIyMjIyMjIyMgCiMgLy8gVGhpcyBmdW5jdGlvbiBjYWxjdWxhdGVzIGFuZCByZXR1cm5zIGEgdmVjdG9yIG9mIHBlcmNlbnRhZ2Ugb2YgZXhwZWN0ZWQgZHJvcGxldHMgY29udGFpbmluZyBtb3JlIHRoYW4gb25lIGNlbGwgZm9yIGVhY2ggMTB4IGZpbGVzLgojIC8vIElucHV0IGZpbGUgbXVzdCBiZSBhIHZlY3RvciBvZiBTZXVyYXQgb2JqZWN0cwojIC8vIFRoZSBlc3RpbWF0ZWQgcGVyY2VudGFnZSBvZiBtdWx0aXBsZXRzIGlzIGNhbGN1bGF0ZWQgYnkgYSBsaW5lYXIgZnVuY3Rpb24gcHJvdmlkZWQgYnkgMTBYIGJhc2VkIG9uIHRoZSBudW1iZXIgcmVjb3ZlcmVkIGNlbGxzCmVzdGltYXRlX3BlcmNlbnRhZ2VfbXVsdGlwbGV0cyA8LSBmdW5jdGlvbihzb2JqKSB7CiAgZXN0aW1hdGVkX211bHRpcGxldHMgPC0gKGRpbShzb2JqKVsyXSAvIDEyNTApIC8gMTAwICMgZXN0aW1hdGVkIHBlcmNlbnRhZ2Ugb2YgbXVsdGlwbGV0cyBpcyBkZXRlcm1pbmVkIGJ5IHRoZSBudW1iZXIgb2YgcmVjb3ZlcmVkIGNlbGxzIGFjY29yZGluZyB0byAxMFggZ2Vub21pY3M6IGxpbmVhciBmb3JtdWxhOiAlbXVsdGlwbGV0ID0gbnVtLWNlbGxzIC8gMTI1MAogIHJldHVybihsaXN0KGVzdGltYXRlZF9tdWx0aXBsZXRzKSkKfQojIEV4ZWN1dGUgZXN0aW1hdGVfcGVyY2VudGFnZV9tdWx0aXBsZXRzIGZ1bmN0aW9uCnBlcmNlbnQubXVsdGlwbGV0cyA8LSBzYXBwbHkoc29ial9saXN0LCBlc3RpbWF0ZV9wZXJjZW50YWdlX211bHRpcGxldHMpCnByaW50KHNvYmpfbGlzdCkKYGBgCiogQWZ0ZXIgZmlsdGVyaW5nIHRoZSBvYmplY3RzIGJhc2VkIG9uIHRoZSBhYnNvbHV0ZSBtZWRpYW4gZGV2aWF0aW9uLCB5b3UgY2FuIHRha2UgYSBjbG9zZSBsb29rIGF0IHRoZSBudW1iZXIgb2Ygc2FtcGxlcyBhZ2FpbiBhbmQgc2VlIGhvdyBtYW55IGNlbGwgd2VyZSByZW1vdmVkIHdoZW4gY29tcGFyZWQgdG8gdGhlIHByZXZpb3VzIHN0ZXA6CiAgLSBBYnNvbHV0ZSBtZWRpYW4gZGV2aWF0aW9uIHRocmVzaG9sZCBpcyBzZXQgaW4gYSB3YXkgdG8gcmVtb3ZlIHRoZSB2ZXJ5IGV4dHJlbWUgY2VsbHMgaW4gY2FzZSBzb21lIHNsaXBwZWQgdGhyb3VnaCB0aGUgQ2VsbHJhbmdlciBmaWx0ZXJpbmcuCiAgLSBUaGUgZmlsdGVyaW5nIGhlcmUgd2lsbCBvZnRlbiBub3QgcmVtb3ZlIG1vcmUgdGhhbiAyMC01MCBjZWxscyBhbmQgd2lsbCBub3QgaW1wYWN0IHRoZSBwcmUtcHJvY2Vzc2luZyBhbGdvcml0aG1zLiAKICAtIFRoaXMgc3RlcCBkb2VzIGhhdmUgZ3JlYXQgaW1wYWN0IGlmIHlvdSBjaG9vc2UgdG8gd29yayB3aXRoIHRoZSByYXdfZmVhdHVyZV9iY19tYXRyaXguIEZvciBhIGdvb2QgcmVhc29uIHRvby4uLiB1bmxlc3MgeW91IGFyZSBpbiBsb3ZlIHdpdGggZW1wdHkgZHJvcGxldHMuLi4KCiogQWdhaW4sIGluIHRoZSBjaHVuayBiZWxvdyB5b3Ugc2hvdWxkIHNlZSBoYXcgbWFueSBjZWxscyB5b3UgbG9zdC4gd2hlbiBjb21wYXJlZCB0byB0aGUgcHJldmlvdXMgc3RlcC4gCmBgYHtyIGFwcGx5IGJhc2ljIGZpbHRlcmluZyB0byBlYWNoIFNldWF0IG9iamVjdCwgZWNobz1GQUxTRX0KIyMjIyMjIyMjIyMjIyMjIyMjIyMgQ2h1bmsgIyMjIyMjIyMjIyMjIyMjIyMjIyMgCiMgLy8gVGhpcyBjaHVuayBpbXBvcnRzIHRoZSBwcmV2aW91c2x5IG1hZGUgb2JqZWN0IGFuZCByZW1vdmVzIGV4dHJlbWUgY2VsbHMgYmFzZWQgb24gQWJzb2x1dGUgbWVkaWFuIGRldmlhdGlvbgojIC8vIFRoZSBmaWx0ZXJpbmcgaXMgdmVyeSBzdWJ0bGUgYW5kIHdpbGwgd2lsbCBvbmx5IHJlbW92ZSB0aGUgdmVyeSBleHRyZW1lIGNlbGxzCiMgLy8gT2Z0ZW4gbm8gbW9yZSB0aGFuIGEgaGFuZGZ1bCBvZiBjZWxscyB3aWxsIGJlIHJlbW92ZWQgYW5kIHRoaXMgd2lsbCBub3QgaW1wYWN0IHRoZSBwcmUtcHJvY2Vzc2luZyBhbGdvcml0aG1zCiMgLy8gVGhpcyBjaHVuayBpcyBleGVjdXRlZCB1c2luZyB0d28gc2VwYXJhdGUgZnVuY3Rpb25zIChpZGVudGlmeWluZyBhbmQgcmVtb3Zpbmcgb3V0bGllcikKIyMjIyMjIyMjIyMjIyMjIyMjIyMgICAgICAgIyMjIyMjIyMjIyMjIyMjIyMjIyMgCgojIyMjIyMjIyMjIGZ1bmN0aW9uICMjIyMjIyMjIyMgCiMgLy8gRnVuY3Rpb24gdG8gY2FsY3VsYXRlIGFuZCByZXR1cm4gb3V0bGllcnMgYmFzZWQgb24gYWJzb2x1dGUgbWVkaWFuIGRldmlhdGlvbnMKIyAvLyBUaGUgaW5wdXQgZmlsZSBtdXN0IGEgdmVjdG9yIG9mIG9iamVjdHMKY2FsX291dGxpZXIgPC0gZnVuY3Rpb24oc29iaiwgbWV0cmljLCBubWFkcyl7CiAgTSA8LSBzb2JqQG1ldGEuZGF0YVtbbWV0cmljXV0KICBtZWRpYW5fTSA8LSBtZWRpYW4oTSwgbmEucm0gPSBUUlVFKQogIG1hZF9NIDwtIG1hZChNLCBuYS5ybSA9IFRSVUUpCiAgb3V0bGllciA8LSAoTSA8IChtZWRpYW5fTSAtIG5tYWRzICogbWFkX00pKSB8IChNID4gKG1lZGlhbl9NICsgbm1hZHMgKiBtYWRfTSkpCiAgcmV0dXJuKG91dGxpZXIpCn0KCiMjIyMjIyMjIyMgRnVuY3Rpb24gIyMjIyMjIyMjIyAKIyAvLyBGdW5jdGlvbiB0byByZW1vdmUgb3V0bGllcnMgYW5kIHJldHVybiBjbGVhbiBvYmplY3QKIyAvLyBUaGUgaW5wdXQgZmlsZSBtdXN0IGEgdmVjdG9yIG9mIG9iamVjdHMKcmVtX291dGxpZXIgPC0gZnVuY3Rpb24oc29iail7CiAgCiMgIHNvYmogPC0gUmVhZDEwWChmaWxlLnBhdGgocGFyZW50X2RpcmVjdG9yeSwgc2FtcGxlX25hbWVzLCAib3V0cy9yYXdfZmVhdHVyZV9iY19tYXRyaXgvIikpCiMgIHNvYmogPC0gQ3JlYXRlU2V1cmF0T2JqZWN0KGNvdW50cyA9IHNvYmosIG1pbi5jZWxscyA9IDEwLCBtaW4uZmVhdHVyZXMgPSAyMDApCiMgIHNvYmokc2FtcGxlX25hbWVzIDwtIHNhbXBsZV9uYW1lcwogIAogICMgYWRkIGJRQyBtZXRyaWNzCiAgc29iaiRsb2cxcF90b3RhbF9jb3VudHMgPC0gbG9nMXAoc29iakBtZXRhLmRhdGEkbkNvdW50X1JOQSkKICBzb2JqJGxvZzFwX25fZ2VuZXNfYnlfY291bnRzIDwtIGxvZzFwKHNvYmpAbWV0YS5kYXRhJG5GZWF0dXJlX1JOQSkKIyAgc29ialtbInBlcmNlbnQubXQiXV0gPC0gUGVyY2VudGFnZUZlYXR1cmVTZXQoc29iaiwgcGF0dGVybiA9ICJNSVRPQ0hPTkRSSUFMIikKICAKICAjIEZpbmQgb3V0bGllcnMgdXNpbmcgdGhlICJjYWxfb3V0bGllciIgZnVuY3Rpb246CiAgYm9vbF92ZWN0b3IgPC0gIWNhbF9vdXRsaWVyKHNvYmosICJsb2cxcF90b3RhbF9jb3VudHMiLCA1KSAmICFjYWxfb3V0bGllcihzb2JqLCAibG9nMXBfbl9nZW5lc19ieV9jb3VudHMiLCA1KSAjICYgIWNhbF9vdXRsaWVyKHNvYmosICJwZXJjZW50Lm10IiwgMTApCiAgc29iaiA8LSBzdWJzZXQoc29iaiwgY2VsbHMgPSB3aGljaChib29sX3ZlY3RvcikpCiAgcmV0dXJuKHNvYmopCn0KCiMgUHJpbnQgdGhlIG91dHB1dCBmb3IgY29udHJvbApzb2JqX2xpc3QgPC0gc2FwcGx5KHNvYmpfbGlzdCwgcmVtX291dGxpZXIpCmZvciAoaSBpbiAxOmxlbmd0aCh4ID0gc29ial9saXN0KSkgewogIHByaW50KHNvYmpfbGlzdFtpXSkKfQpgYGAKCiMjIyMgUUMgcGxvdHM6ICMjIyMKCiMjIyMjIERlc2NyaXB0aW9uOiAjIyMjIwoKKiBUaGUgbnVtYmVyIG9mIHVuaXF1ZSBnZW5lcyBkZXRlY3RlZCBpbiBlYWNoIGNlbGw6IAogIC0gRW1wdHkgZHJvcGxldHMgYW5kIGxvdyBxdWFsaXR5IGNlbGxzIG9mdGVuIGhhdmUgdmVyeSBmZXcgZ2VuZXMgYW5kIG1hbnkgMCBjb3VudHMKICAtIENlbGwgbXVsdGlwbGV0cyAoZG91YmxldHMpIG9mdGVuIGhhdmUgdmVyeSBoaWdoIGdlbmUgY291bnQuCiAgLSBJZiB5b3Ugd29yayB3aXRoIHRoZSBmaWx0ZXJlZCBjb3VudHMgbWF0cml4IGFzIGEgc3RhcnRpbmcgcG9pbnQgeW91IHdpbGwgbm90IGZpbmQgY2VsbHMgd2l0aCA8NTAwIFVNSXMuCgoqIFVzZXIgZXhwZWN0YXRpb246CiAgLSBJbiBnZW5lcmFsLCB5b3Ugc2hvdWxkIGhhdmUgYW4gZXhwZWN0YXRpb24gb2YgaG9tZSBtYW55IGdlbmVzL1VNSXMgdGhlIG1ham9yaXR5IG9mIHlvdXIgY2VsbHMgY29udGFpbi4gTW9zdCBvZiB0aGUgdGltZSwgVGhlIFVNSSBjb3VudHMgcGVyIGNlbGwgc2hvdWxkIGJlIGF0IGxlYXN0IH41MDAgKGFuZCB+MjAwIGdlbmVzKSwgdGhhdCBpcyBjb25zaWRlcmVkIHRoZSBsb3cgZW5kIG9mIHdoYXQgeW91IHNob3VsZCBleHBlY3QuIEhvd2V2ZXIsIGNlbGwgdGhhdCBleHByZXNzIGV4dHJlbWVseSBsb3cgbnVtYmVyIG9mIGdlbmVzIHdpbGwgaGF2ZSBVTUkgY291bnQgYmVsb3cgfjUwMC4gVGhlIHNhbWUgaXMgdHJ1ZSBmb3IgYSBmYWlsZWQgZXhwZXJpbWVudHMgd2l0aCBkZWdyYWRlZCBSTkFzLiBUaHVzIHRoZSB1c2VyIHNob3VsZCBoYXZlIGFuIGNsZWFyIGV4cGVjdGF0aW9uLgogIAoqIFRoZSBwZXJjZW50YWdlIG9mIHJlYWRzIG1hcHBlZCB0byB0aGUgbWl0b2Nob25kcmlhbCBnZW5vbWU6IAogIC0gT2Z0ZW4sIGR5aW5nIGNlbGxzIChvciBsb3cgcXVhbGl0eSBjZWxscykgaGF2ZSBsb3RzIG9mIG1pdG9jaG9uZHJpYWwgY29udGFtaW5hdGlvbiwgcG9zc2libHkgZHVlIHRvIGxvc3Mgb2YgY3l0b3BsYXNtaWMgUk5BIGZyb20gcGVyZm9yYXRlZCBjZWxscy4gVGhlIHJlYXNvbmluZyBpcyB0aGF0IG1pdG9jaG9uZHJpYSBhcmUgbGFyZ2VyIHRoYW4gaW5kaXZpZHVhbCB0cmFuc2NyaXB0IG1vbGVjdWxlcyBhbmQgbGVzcyBsaWtlbHkgdG8gZXNjYXBlIHRocm91Z2ggdGVhcnMgaW4gdGhlIGNlbGwgbWVtYnJhbmUuCiAgLSBOb3RlIHRoYXQgZm9yIHNpbmdsZS1udWNsZWkgc2FtcGxlcywgTVQgZ2VuZXMgYXJlIG9mdGVuIHN0aWxsIHByZXNlbnQsIGJ1dCBhdCBtdWNoIGxvd2VyIHF1YW50aXRpZXMgd2hlbiBjb21wYXJlZCB0byBzaW5nbGUtY2VsbCBkYXRhLgogIC0gTWl0b2Nob25kcmlhbCBRQyBtZXRyaWNzIGFyZSBjYWxjdWxhdGVzIHdpdGggdGhlIHBlcmNlbnRhZ2Ugb2YgY291bnRzIG9yaWdpbmF0aW5nIGZyb20gYSBzZXQgb2YgZmVhdHVyZXMuCiAgLSBXZSB1c2UgdGhlIHNldCBvZiBhbGwgZ2VuZXMgc3RhcnRpbmcgd2l0aCAiTVQtIiBvciAibXQtIiBhcyBtaXRvY2hvbmRyaWFsIGdlbmVzICh3aGljaCBoYXZlIGJlZW4gaW5zZXJ0ZWQvbWFuaXB1bGF0ZWQgaW4gQUxMIE1UIGdlbmVzKS4gKFRoZSBFbnNlbWJsIGRhdGFiYXNlIGlzIHVzZWQgdG8gZmluZCB0aGUgTVQgZ2VuZXMgaW4gdGhlIHNwZWNpZXMhKQogIAojIyMjIyBSZXN1bHRzOiAjIyMjIwoKKiBCYXJwbG90czoKICAtIFJlcHJlc2VudGluZyB0aGUgZGlzdHJpYnV0aW9uIGFuZCBudW1iZXIgb2YgZ2VuZSBjb3VudHMsIHRyYW5zY3JpcHQgY291bnRzLCBhbmQgcGVyY2VudGFnZSBvZiBNVCByZWFkcyBwZXIgY2VsbC4gR2VuZXJhbGx5LCBoaWdoIGZyYWN0aW9uIG9mIE1UIHJlYWRzIGluIGNvbWJpbmF0aW9uIHdpdGggbG93IGdlbmUvdHJhbnNjcmlwdCBjb3VudHMgaW5kaWNhdGUgc3RyZXNzZWQgb3IgZGVhZCBjZWxscy4gSG93ZXZlciwgaGlnaGx5IHByb2xpZmljIHN0ZW0gb3IgY2FuY2VyLWxpa2UgY2VsbCBhcmUgb2Z0ZW4gcmljaCBpbiBNVHMsIHdoZXJlYXMgc29tZSBpbW11bmUgY2VsbHMgc3VjaCBhcyBuZXV0cm9waGlsZXMgYXJlIGluIGxvd2VyIGVuZCBvZiB0aGUgc3BlY3RydW0gaW4gdGVybXMgb2YgZ2VuZSBhbmQgdHJhbnNjcmlwdCBjb3VudHMuIAogIC0gVGhlIGRhc2hlZCByZWQgYW5kIG9yYW5nZSBsaW5lcyByZXByZXNlbnQgdGhlIHRoZW9yZXRpY2FsIHRocmVzaG9sZHMgKFJlZDogMTAlIE1ULCAyMDAgbkdlbmVzLCA1NTAgblVVTUlzLiBPcmFuZ2U6IDcuNSUgTVQpCmBgYHtyIFFDIE1ULCBmaWcuaGVpZ2h0PTgsIGZpZy53aWR0aD0xNSwgZWNobz1GQUxTRSwgbWVzc2FnZT1GQUxTRX0KIyMjIyMjIyMjIyMjIyMjIyMjIyMgQ2h1bmsgIyMjIyMjIyMjIyMjIyMjIyMjIyMgCiMgLy8gVGhpcyBjaHVuayBwbG90cyBoaXN0b2dyYW1zIHdpdGggdGhlIGZyZXF1ZW5jeSAoY2VsbHMpIGFzIGEgZnVuY3Rpb24gb2YgbkdlbmVzLCBuVU1JcyBhbmQgTVQgcGVyY2VudGFnZQojIC8vIEEgc2VwYXJhdGUgZnVuY3Rpb25zIGNhbGN1bGF0ZXMgYW5kIGFkZHMgdGhlIHBlcmNlbnQgTVQgdG8gdGhlIG9iamVjdCBNZXRhZGF0YQojIC8vIEZvciBlYWNoIGhpc3RvZ3JhbSBsaW5lcyBpbiBlaXRoZXIgcmVkLCBvcmFuZ2UgYW5kIGdyZWVuIHJlcHJlc2VudCB0aGUgdGhyZXNob2xkcyAKIyMjIyMjIyMjIyMjIyMjIyMjIyMgICAgICAgIyMjIyMjIyMjIyMjIyMjIyMjIyMgCgojIyMjIyMjIyMjIEZ1bmN0aW9uICMjIyMjIyMjIyMgCiMgLy8gVGhpcyBmdW5jdGlvbiBjYWxjdWxhdGVzIGFuZCByZXR1cm5zIHRoZSBwZXJjZW50YWdlIG9mIG1pdG9jaG9uZHJpYWwgZ2VuZXMgcGVyIG9iamVjdCBhbmQgYWRkcyBpdCB0byB0aGUgTWV0YURhdGEgc2xvdCAob2JqQG1ldGFkYXRhKQojIC8vIElucHV0IGZpbGUgbXVzdCBiZSBhIHZlY3RvciBvZiBvYmplY3RzCmdldF9NVF9wZXJjZW50YWdlIDwtIGZ1bmN0aW9uKHNvYmopIHsKICAgaWYgKGdyZXBsKCJtdC0iLCBNVF9nZW5lc1sxXSkgPT0gVFJVRSkgewogICBzb2JqW1sicGVyY2VudC5tdCJdXSA8LSBQZXJjZW50YWdlRmVhdHVyZVNldChzb2JqLCBwYXR0ZXJuID0gIm10LSIpICMgc2VhcmNoIGZvciAtbXQgcGFzdGVybiBpZiBsb3dlciBjYXNlIAogfSBlbHNlIHsgc29ialtbInBlcmNlbnQubXQiXV0gPC0gUGVyY2VudGFnZUZlYXR1cmVTZXQoc29iaiwgcGF0dGVybiA9ICJNVC0iKQogfQogIHJldHVybihzb2JqKQp9CiMgRXhlY3V0ZSB0aGUgZnVuY3Rpb24gZ2V0X01UX3BlcmNlbnRhZ2UKc29ial9saXN0IDwtIHNhcHBseShzb2JqX2xpc3QsIGdldF9NVF9wZXJjZW50YWdlKQoKIyB2aXN1YWxpemUgTVQgcGVyY2VudGFnZSBpbiBjZWxscwpnZXRfaGlzdG9ncmFtc19RQyA8LSBmdW5jdGlvbihzb2JqKSB7CiAgICAgICMgdmlzdWFsaXplIHBlcmNlbnRhZ2UgTVQgZ2VuZXMgcGVyIGNlbGwKICAgICAgaDEgPC0gaGlzdChzb2JqW1sicGVyY2VudC5tdCJdXSRwZXJjZW50Lm10LCBicmVha3MgPSAzMCwgeGxhYiA9ICJQZXJjZW50YWdlIE1pdG9jaG9uZHJpYWwgR2VuZXMgKCUpIiwgeWxhYiA9ICJGcmVxdWVuY3kgKGNlbGxzKSIsIAogICAgICAgICAgICAgbWFpbiA9IHBhc3RlKCJIaXN0b2dyYW06IFFDIE1UIiwgc29iakBtZXRhLmRhdGFbMSwxXSwgc2VwID0gIiAtICIpLCAKICAgICAgICAgICAgIGNvbCA9ICJ3aGl0ZSIsIGxhYmVscyA9IFRSVUUsIHBsb3QgPSBUUlVFKSAKICAgICAgYWJsaW5lKHYgPSAxMCwgY29sPSJyZWQiLCBsd2Q9MywgbHR5PTIpCiAgICAgIGFibGluZSh2ID0gNy41LCBjb2w9Im9yYW5nZSIsIGx3ZD0zLCBsdHk9MikKICAgICAgIyB2aXN1YWxpemUgbnVtYmVyIG9mIGdlbmVzIGluIGNlbGxzCiAgICAgIGgyIDwtIGhpc3Qoc29ialtbIm5GZWF0dXJlX1JOQSJdXSRuRmVhdHVyZV9STkEsIGJyZWFrcyA9IDMwLCB4bGFiID0gIk51bWJlciBvZiBnZW5lcyIsIHlsYWIgPSAiRnJlcXVlbmN5IChjZWxscykiLCAKICAgICAgICAgICAgIG1haW4gPSBwYXN0ZSgiSGlzdG9ncmFtOiBRQyBudW1iZXIgb2YgZ2VuZXMiLCBzb2JqQG1ldGEuZGF0YVsxLDFdLCBzZXAgPSAiIC0gIiksIAogICAgICAgICAgICAgY29sID0gIndoaXRlIiwgbGFiZWxzID0gVFJVRSwgcGxvdCA9IFRSVUUpCiAgICAgIGFibGluZSh2ID0gMjAwLCBjb2w9InJlZCIsIGx3ZD0zLCBsdHk9MikKICAgICAgIyB2aXN1YWxpemUgbnVtYmVyIG9mIFVNSXMgKG1vbGVjdWxlcykgaW4gY2VsbHMKICAgICAgaDMgPC0gaGlzdChzb2JqW1sibkNvdW50X1JOQSJdXSRuQ291bnRfUk5BLCBicmVha3MgPSAzMCwgeGxhYiA9ICJOdW1iZXIgb2YgVU1JcyAoUk5BIG1vbGVjdWxlcykiLCB5bGFiID0gIkZyZXF1ZW5jeSAoY2VsbHMpIiwgCiAgICAgICAgICAgICBtYWluID0gcGFzdGUoIkhpc3RvZ3JhbTogUUMgbnVtYmVyIG9mIFVNSXMiLCBzb2JqQG1ldGEuZGF0YVsxLDFdLCBzZXAgPSAiIC0gIiksIAogICAgICAgICAgICAgY29sID0gIndoaXRlIiwgbGFiZWxzID0gVFJVRSwgcGxvdCA9IFRSVUUpCiAgICAgIGFibGluZSh2ID0gNTAwLCBjb2w9InJlZCIsIGx3ZD0zLCBsdHk9MikKICAgICAgcmV0dXJuKCkKfQojIEV4ZWN1dGUgZ2V0X2hpc3RvZ3JhbXNfUUMgZnVuY3Rpb24KaGlzdCA8LSBzYXBwbHkoc29ial9saXN0LCBnZXRfaGlzdG9ncmFtc19RQykKCgojIyMjIyMjIyMjIyMgU0VDT05EIFdBWSBUTyBETyBJVCwgRk9SIFNBVklORyBJTUFHRVMgIyMjIyMjIyMjIyMjIyMKI2ZvciAoaSBpbiAxOmxlbmd0aCh4ID0gc29ial9saXN0KSkgewogICMgdmlzdWFsaXplIHBlcmNlbnRhZ2UgTVQgZ2VuZXMgcGVyIGNlbGwKIyAgaDEgPC0gaGlzdChzb2JqX2xpc3RbW2ldXVtbInBlcmNlbnQubXQiXV0kcGVyY2VudC5tdCwgYnJlYWtzID0gMzAsIHhsYWIgPSAiUGVyY2VudGFnZSBNaXRvY2hvbmRyaWFsIEdlbmVzICglKSIsIHlsYWIgPSAiRnJlcXVlbmN5IChjZWxscykiLCAKIyAgICAgICAgICAgICBtYWluID0gcGFzdGUoIkhpc3RvZ3JhbTogUUMgTVQiLCBzb2JqX2xpc3RbW2ldXUBtZXRhLmRhdGFbMSwxXSwgc2VwID0gIiAtICIpLCBjb2wgPSAid2hpdGUiLCBsYWJlbHMgPSBUUlVFLCBwbG90ID0gVFJVRSkgCiAgIyB2aXN1YWxpemUgbnVtYmVyIG9mIGdlbmVzIGluIGNlbGxzCiMgIGgyIDwtIGhpc3Qoc29ial9saXN0W1tpXV1bWyJuRmVhdHVyZV9STkEiXV0kbkZlYXR1cmVfUk5BLCBicmVha3MgPSAzMCwgeGxhYiA9ICJOdW1iZXIgb2YgZ2VuZXMiLCB5bGFiID0gIkZyZXF1ZW5jeSAoY2VsbHMpIiwgCiMgICAgICAgICAgICAgbWFpbiA9IHBhc3RlKCJIaXN0b2dyYW06IFFDIG51bWJlciBvZiBnZW5lcyIsIHNvYmpfbGlzdFtbaV1dQG1ldGEuZGF0YVsxLDFdLCBzZXAgPSAiIC0gIiksIGNvbCA9ICJ3aGl0ZSIsIGxhYmVscyA9IFRSVUUsIHBsb3QgPSBUUlVFKQogICMgdmlzdWFsaXplIG51bWJlciBvZiBVTUlzIChtb2xlY3VsZXMpIGluIGNlbGxzCiMgIGgzIDwtIGhpc3Qoc29ial9saXN0W1tpXV1bWyJuQ291bnRfUk5BIl1dJG5Db3VudF9STkEsIGJyZWFrcyA9IDMwLCB4bGFiID0gIk51bWJlciBvZiBVTUlzIChSTkEgbW9sZWN1bGVzKSIsIHlsYWIgPSAiRnJlcXVlbmN5IChjZWxscykiLCAKIyAgICAgICAgICAgICBtYWluID0gcGFzdGUoIkhpc3RvZ3JhbTogUUMgbnVtYmVyIG9mIGdlbmVzIiwgc29ial9saXN0W1tpXV1AbWV0YS5kYXRhWzEsMV0sIHNlcCA9ICIgLSAiKSwgY29sID0gIndoaXRlIiwgbGFiZWxzID0gVFJVRSwgcGxvdCA9IFRSVUUpIAojICBwcmludChoMSkgIyBTQVZFIElUIEZPUiBQSVBFTElORQojICBwcmludChoMSkKIyAgcHJpbnQoaDEpCiN9CgoKCgoKIyMjIyMjIyMgVEVTVElORyBDT0RFCgoKCgoKICAgICAgCmBgYAoKIyMjIyBIZXJlIHdlIHdpbGwgdmlzdWFsaXplIHRoZSBkaXN0cmlidXRpb24gb2YgbkdlbmVzIGFuZCBuVU1JcyBhbmQgdGhlIGNvbXBsZXhpdHkgb2YgdGhlIGNlbGxzOiAjIyMjCgojIyMjIyBEZXNjcmlwdGlvbjogIyMjIyMKCiogVGVybWlub2xvZ3k6CiAgLSBuRmVhdHVyZV9STkEgaXMgdGhlIG51bWJlciBvZiBnZW5lcyBkZXRlY3RlZCBpbiBlYWNoIGNlbGwgKHZpb2xpbiBwbG90KS4KICAtIG5Db3VudF9STkEgaXMgdGhlIHRvdGFsIG51bWJlciBvZiBtb2xlY3VsZXMgZGV0ZWN0ZWQgd2l0aGluIGEgY2VsbCAoVU1JcykgKHZpb2xpbiBwbG90KS4KICAtIHBlcmNlbnQubXQgaXMgdGhlIHBlcmNlbnRhZ2Ugb2YgbWl0b2Nob25kcmlhbCBVTUlzIHdpdGhpbiBhIGNlbGwgKHZpb2xpbiBwbG90KS4KICAtIENlbGwgY29tcGxleGl0eWlzIHRoZSBwcm9wb3J0aW9uIG9mIG5HZW5lcyByYWx0aXZlIHRvIHRoZSBudW1iZXIgb2YgdHJhbnNjcmlwdHMgKFJOQS1tb2xlY3VsZXMvVU1JcykuCiAgLSBMb3cgY29tcGxleGl0eSBjZWxscyBpcyBhIGNlbGwgdGhhdCBoYXMgZmV3IGdlbmVzLCBidXQgbW9yZSB0cmFuc2NyaXB0cy4KICAtIEhpZ2ggY29tcGxleGl0eSBjZWxscyBpcyBhIGNlbGwgdGhhdCBtb3JlIGdlbmVzIGFuZCBsZXNzIHRyYW5zY3JpcHRzLgogIC0gRG9taW5hbnQgZ2VuZSBpcyBhIGdlbmUgdGhhdCBoYXMgdGhlIGhpaWdoZXN0IGV4cHJlc3Npb24gaW4gYSBjZWxsIHJlbGF0aXZlIHRvIHRoZSBvdGhlciBnZW5lcy4KCiMjIyMjIFJlc3VsdHM6ICMjIyMjCgoqIFZpb2xpbiBwbG90czoKICAtIExvdyBuRmVhdHVyZV9STkEgZm9yIGEgY2VsbCBpbmRpY2F0ZXMgdGhhdCBpdCBtYXkgYmUgZGVhZC9keWluZyBvciBhbiBlbXB0eSBkcm9wbGV0LiBJdCBpcyB1c3VhbGx5IGFjY2VwdGVkIHRoYXQgY2VsbHMgdGhhdCBhcmUgcG9vciBxdWFsaXR5IGFyZSBsaWtlbHkgdG8gaGF2ZSBsb3cgZ2VuZXMgYW5kIFVNSXMgcGVyIGNlbGwsIGFuZCBjb3JyZXNwb25kIHRvIHRoZSBkYXRhIHBvaW50cyBpbiB0aGUgYm90dG9tIGxlZnQgcXVhZHJhbnQgb2YgdGhlIHBsb3QuIEdvb2QgY2VsbHMgd2lsbCBnZW5lcmFsbHkgZXhoaWJpdCBib3RoIGhpZ2hlciBudW1iZXIgb2YgZ2VuZXMgcGVyIGNlbGwgYW5kIGhpZ2hlciBudW1iZXJzIG9mIFVNSXMuIEJ1dCBiZSBjYXJlZnVsIGhlcmUsIHNvbWUgY2VsbCB0eXBlcyBhcmUga25vd24gdG8gaGF2ZSBsb3cgZ2VuZXMgYW5kIFVNSXMuCiAgLSBIaWdoIG5Db3VudF9STkEgYW5kL29yIG5GZWF0dXJlX1JOQSBpbmRpY2F0ZXMgdGhhdCB0aGUgImNlbGwiIG1heSBpbiBmYWN0IGJlIGEgZG91YmxldCAob3IgbXVsdGlwbGV0KS4gQnV0IGJlIGNhcmVmdWwgYWdhaW4sIHNvbWUgY2VsbCB0eXBlcyBhcmUga25vd24gdG8gaGF2ZSBzdXBlciBoaWdoIGdlbmVzIGFuZCBVTUlzIChpLmUuIGRldmVsb3BpbmcgY2VsbHMsIGNhbmNlciwgc3RlbS1jZWxscykuCiAgCiogUGVyY2VudC1NVCB2cyBuR2VuZSAvIFBlcmNlbnQtTVQgdnMgblVNSSBwbG90OiAKICAtIEFnYWluLCBmb3IgYmFkIGNlbGwgd2UgZXhwZWN0IHRvIHNlZSB0aGUgaGlnaCBwZXJjZW50YWdlIE1UIHdpdGggbG93IG51bWJlciBvZiBnZW5lcy9VTUlzICh1bmxlc3MgZXhwZWN0ZWQgb3RoZXJ3aXNlLCBlLmcuIGNhcmRpYWMgY2VsbHMpLgogIC0gVGhlIGRhc2hlZCByZWFkIGxpbmUgcmVwcmVzZW50cyBhIHRoZW9yZXRpY2FsIE1UIGxpbWl0IG9mIDEwJSBhbmQgb3JhbmdlIDUlLgoKKiBuVU1JcyB2cyBuR2VuZXMgcGxvdCAoYWxzbyBsb2cgc2NhbGVkIHZlcnNpb24pOiAKICAtIEVtcHR5IGRyb3BsZXRzIGFuZCBsb3cgcXVhbGl0eSBjZWxscyBvZnRlbiBoYXZlIHZlcnkgZmV3IGdlbmVzIGFuZCBtYW55ICIwIiBnZW5lcy9VTUkgY291bnRzIChNaW5pbXVtIG9mIDUwMCBVTUlzIGlmIHlvdSB1c2UgdGhlIGZpbHRlcmVkIGNvdW50cyBtYXRyaXgpLgogIC0gQ2VsbCBtdWx0aXBsZXRzIChkb3VibGV0cykgb2Z0ZW4gaGF2ZSB2ZXJ5IGhpZ2ggZ2VuZS9VTUkgY291bnQuCiAgLSBOb3RpY2UgdGhhdCBjZWxsIHdpdGggdGhlIGhpZ2hlc3QgbWl0b2Nob25kcmlhbCBnZW5lcyBhcmUgbG9jYXRlZCBpbiB0aGUgYm90dG9tLWxlZnQgb2YgdGhlIHBsb3QsIGluZGljYXRpbmcgdGhhdCB0aGVzZSBhcmUgdHJ1bHkgYmFkIGNlbGwgY29uc2lkZXJpbmcgdGhleSBjb250YWluIGhpZ2ggTVQgcGVyY2VudGFnZSwgYnV0IGxvdyBudW1iZXIgb2YgZ2VuZXMvVU1Jcy4gS2VlcCBpbiBtaW5kIHRoYXQgZ29vZCBjZWxscyBjb3VsZCBhbHNvIGhhdmUgbnVtYmVyIG9mIE1UIGdlbmVzLCB0aGVzZSBjZWxscyBhcmUgb2Z0ZW4gYWN0aXZhdGVkIGNlbGxzIChpLmUuIFN0ZW0vY2FuY2VyL2N5Y2xpbmcvZGV2ZWxvcGluZyBjZWxscykuIE5vdyBpdCBjb3VsZCBhIGxpdHRsZSB0cm91YmxpbmcgaWYgdGhlIG1ham9yaXR5IG9mIHlvdXIgaGlnaCBNVCBjZWxscyBhbHNvIGNvbnRhaW4gbWFueSBnZW5lcy9VTUlzLCBlc3BlY2lhbGx5IGlmIHlvdSBkbyBub3QgZXhwZWN0IGFjdGl2YXRlZCBjZWxsIHR5cGVzIGluIHlvdXIgZGF0YS4gWW91IGhhdmUgdG8gYmUgYXdhcmUgd2l0aCB0aGUgdHlwZSBvZiBjZWxsIHlvdSBhcmUgd29ya2luZyB3aXRoLgogIC0gSW4gdGhlIG5VTUkgdnMgbkdlbmVzIHBsb3Qgd2UgY2FuIGFsc28gc2VlIHRoZSBjb21wbGV4aXR5IG9mIHRoZSBkYXRhc2V0IHdpdGggcG90ZW50aWFsIGVycm9ycy4gR2VuZXJhbGx5LCB3ZSBleHBlY3QgYSBsaW5lYXIgcmVsYXRpb25zaGlwIGJldHdlZW4gdGhlIG51bWJlciBvZiBnZW5lcyBhbmQgVU1JcyBpbiB0aGlzIHBsb3QuIElmIGNlbGxzIGluIHRoZSBwbG90IGFyZSBza2V3ZWQgZmFyIGZyb20gdGhlIG1pZGRsZSBsaW5lIHRvd2FyZHMgdGhlIGJvdHRvbS1yaWdodCB0aGlzIGNvdWxkIG1lYW4gdGhhdCB0aGUgZXhwZXJpbWVudCBoYXMgY2FwdHVyZWQgdmVyeSBmZXcgbnVtYmVyIG9mIGdlbmVzIGFuZCB0aG9zZSBzYW1lIGdlbmVzIGhhdmUgYmVlbiBzZXF1ZW5jZWQgbXVsdGlwbGUgdGltZXMuIFNpbWlsYXJseSwgaWYgdGhlIGNlbGxzIGFyZSBza2V3ZWQgdG93YXJkcyB0aGUgdG9wLWxlZnQgdGhpcyBjb3VsZCBtZWFuIHRoYXQgZXhwZXJpbWVudCBoYXMgY2FwdHVyZWQgbWFueSBnZW5lcywgYnV0IHRoZXkgYXJlIG5vdCBzZXF1ZW5jZWQgZGVlcGx5IGVub3VnaCAod2hpY2ggcmVzdWx0cyBpbiBsb3cgbnVtYmVyIG9mIFVNSXMpLiBLZWVwIGluIG1pbmQgdGhhdCBhcyBhIHJlc3VsdCBvZiBSTkEgZGVncmFkYXRpb24sIGEgZmFpbGVkIGV4cGVyaW1lbnQgY291bGQgc3RpbGwgZ2l2ZSB1cyBhIGdvb2QgcGxvdHMuCiAgLSBUaGUgb3JhbmdlIGRhc2hlZCBsaW5lcyBzaG93IHRoZSB0aGVvcmV0aWNhbCBsb3dlciBsaW1pdHMgb2YgVU1JcyAoNTUwKSBhbmQgZ2VuZXMgKDIwMCkuIFRoZSB5ZWxsb3cgZGFzaGVkIGxpbmVzIHNob3cgdGhlIHVwcGVyIGFuZCBsb3dlciBxdWFudGlsZXMgb2YgYm90aCBudW1iZXIgb2YgZ2VuZXMgYW5kIFVNSXMgKGRlZmF1bHQgc2V0IGJldHdlZW4gMi05OCUpLiBJZiB5b3UgY2hvb3NlIGZpbHRlciB0aGUgbnVtYmVyIG9mIGdlbmVzIGFuZCBVTUlzIGJ5IHVzZXItZGVmaW5lZCBxdWFudGlsZXMsIHRoZW4gdGhlIHllbGxvdyBkYXNoZWQgbGluZXMgd2lsbCBiZSBzZXQgYXQgdGhvc2UgbnVtYmVycy4KICAKKiBDb21wbGV4aXR5IHBsb3QgKHRoZSBzaW5ndWxhciBwbG90IGJlbG93KTogCiAgLSBDb21wbGV4aXR5IGNhbiBhbHNvIGJlIHZpc3VhbGl6ZWQgYnkgZGl2aWRpbmcgdGhlIG5HZW5lcyBieSBuVU1JcyBmb3IgZWFjaCBjZWxsLiBIaWdoZXIgdmFsdWVzIGluZGljYXRlIHRoYXQgd2UgYXJlIGdldHRpbmcgc2hhbGxvd2VyIGNvdmVyYWdlIG9mIG1vcmUgZ2VuZXMsIGFuZCBsb3dlciB2YWx1ZXMgbWVhbiB0aGF0IHdlIGFyZSBzZWVpbmcgZmV3ZXIgZ2VuZXMgb3ZlcmFsbC4gCiAgLSBHZW5lcmFsbHksIHdlIGV4cGVjdCB0aGUgbm92ZWx0eSBzY29yZSB0byBiZSBhYm92ZSAwLjgwIChpbmRpY2F0ZWQgd2l0aCBkYXNoZWQgcmVkIGxpbmUpLgogIC0gQXMgdGhlcmUgaXMgYSBsaW5lYXIgcmVsYXRpb25zaGlwIGJldHdlZW4gdGhlIG51bWJlciBvZiBnZW5lcyBhbmQgdHJhbnNjcmlwdHMgZm9yIHRoZSBtYWpvcml0eSBvZiB0aGUgY2VsbHMsIGl0IGlzIGV4cGVjdGVkIHRvIGZpbmQgdGhlIGhpZ2hlc3QgcHJvYmFiaWxpdHkgYXQgYSBnZW5lcy90cmFuc2NyaXB0IHJhdGlvIGJldHdlZW4gMC44NS0wLjk1LCBldmVuIGZvciBsb3ctY29tcGxleGl0eSBjZWxscy4gQSBsYXJnZSBwcm9iYWJpbGl0eSBkZW5zaXR5IGF0IGFueXRoaW5nIGJlbG93IDAuOCBpbmRpY2F0ZXMgYSBmYWlsZWQgZXhwZXJpbWVudCwgYXMgaW5zdWZmaWNpZW50IGdlbmVzIGhhdmUgYmVlbiBjYXB0dXJlZCBpbiBwcm9wb3J0aW9uIHRvIHRyYW5zY3JpcHQgY291bnRzLgogIAoqIFBsb3R0aW5nIGNvbXBsZXhpdHkgYXMgZnVuY3Rpb24gb2YgcGVyY2VudGFnZSBvZiBjb3VudHMgcGVyIGdlbmUgKHRoZSBmaXJzdCB0cmlvIHBsb3RzIGJlbG93KToKICAtIENvbXBsZXhpdHk6IExvZzEwIC0gblVNSXMgdnMgbkdlbmVzOiAgICBBZ2FpbiwgbWFrZSBhbm90aGVyIHBsb3QgYXMgYmVmb3JlIChsb2cxMCAtIG5VTUlzIHZzIG5HZW5lcyBwbG90KSwgYnV0IG5vdyB3ZSBmaXQgYSBsaW5lYXIgbW9kZWwgYW5kIGNhbGN1bGF0ZSB0aGUgcmVzaWR1YWwgZnJvbSB0aGUgbWlkZGxlIHBvaW50IGZvciBlYWNoIGNlbGwuIE5vdyB3ZSBjYW4gY2xlYXJseSB2aXN1YWxpemUgd2hpY2ggY2VsbHMgaGF2ZSBtb3JlIHRyYW5zY3JpcHRzIHZzIGdlbmVzIHJlbGF0aXZlIHRvIHRoZSBtaWRkbGUtbGluZSAob3IgdmljZSB2ZXJzYSkuIFRoaXMgaXMgaW5kaWNhdGVkIGJ5IHRoZSBzdHJlbmd0aCBvZiB0aGUgYmx1ZSBvciByZWQgY29sb3IuCiAgLSBSZXNpZHVhbCB2cyBEZW5zaXR5OiAgICBJbiB0aGlzIHBsb3QsIHdlIGNhbiBzZWUgdGhlIGZyZXF1ZW5jeSAoZGVuc2l0eSkgb2YgY2VsbHMgYXMgYSBmdW5jdGlvbiBpcyB0aGUgcmVzaWR1YWxzIChpLmUuIGRldmlhdGlvbiBmcm9tIHRoZSBsaW5lYXIgcmVncmVzc2lvbikuIFdoYXQgZG8geW91IHNlZSBoZXJlPyBBIG5vcm1hbCBkaXN0cmlidXRpb24gb3Igc2tld2VkIHRvd2FyZHMgdGhlIGxlZnQgb3IgcmlnaHQ/IFRoaXMgZGVuc2l0eSBwbG90IGlzIHNpbXBseSBhbiBhZGRpdGlvbiB0byB0aGUgbGluZWFyIG1vZGVsIGFuZCBpdCBpcyBleHBlY3RlZCB0aGF0IHlvdSBmaW5kIHRoZSBsYXJnZXN0IGRlbnNpdHkgYXJvdW5kIDAsIG1lYW5pbmcgdGhhdCB0aGUgbWFqb3JpdHkgb2YgdGhlIGNlbGxzIHdlcmUgaW5kZWVkIGNsb3NlIHRvIHRoZSBtaWRkbGUgbGluZSBpbiB0aGUgbGluZWFyIHJlZ3Jlc3Npb24uIEp1c3QgbGlrZSBiZWZvcmUsIGlmIHRoZSBncmFwaHMgaXMgc2tld2VkIHRvd2FyZCB0aGUgbGVmdCAobmVnYXRpdmUgcmVzaWR1YWxzKSwgdGhpcyBtZWFucyB0aGF0IHlvdSBtYXkgaGF2ZSBhbiB1bmRlc2lyZWQgbnVtYmVyIG9mIGxvdy1jb21wbGV4aXR5IGNlbGxzLiBMaWtld2lzZSwgaWYgdGhlIGdyYXBoIGlzIHNrZXdlZCB0b3dhcmRzIHRoZSByaWdodCBzaWRlIChwb3NpdGl2ZSByZXNpZHVhbHMpLCB0aGVuIHlvdSBtYXkgbWFueSBoaWdoLWNvbXBsZXhpdHkgY2VsbHMuIFVzdWFsbHksIHN1Y2ggYmVoYXZpb3IgaXMgcmVsYXRlZCB0byBzb21lIHNvcnQgb2YgZmFpbGVkIGV4cGVyaW1lbnQuCiAgLSBSZXNpZHVhbCB2cyBQZXJjZW50YWdlIExhcmdlc3QgZ2VuZXM6ICAgSW4gdGhpcyBwbG90LCBmb3IgZWFjaCBjZWxsLCB3ZSBjYWxjdWxhdGUgdGhlIGdlbmUgd2l0aCB0aGUgaGlnaGVzdCBwZXJjZW50YWdlIG9mIHJlYWRzIGFuZCBwdXQgYWdhaW5zdCB0aGUgcmVzaWR1YWxzLiBZb3UgY2FuIG5vdyBzZWUgYSBzZW1pLWRlbnNpdHkgcGxvdCBhcyBiZWZvcmUsIGJ1dCBub3cgd2l0aCB0aGUgYWN0dWFsIGNlbGxzLiBEbyB5b3Ugc2VlIGEgcGF0dGVybiBoZXJlPyBEbyB5b3Ugc2VlIGFueSBsb3ctY29tcGxleGl0eSBjZWxscyB3aXRoIGEgaGlnaCBwZXJjZW50YWdlIG9mIGEgZG9taW5hbnQgZ2VuZT8gSWRlYWxseSwgd2UgZXhwZWN0IGEgdm9sY2FubyBwbG90IGNlbnRlcmVkIGFyb3VuZCB0aGUgbWlkZGxlLiBJZiB5b3UgaGF2ZSBtYW55IGxvdy1jb21wbGV4aXR5IGNlbGxzIHdpdGggYSBzaWduaWZpY2FudGx5IGluZmxhdGVkIGRvbWluYW50IGdlbmUsIHRoaXMgbWlnaHQgaW5kaWNhdGUgYmFkIGNlbGxzLiBCdXQgZmlyc3QsIHdlIGhhdmUgdG8gZmluZCBvdXQgd2luY2ggZG9taW5hbnQgZ2VuZSB0aGV5IGV4cHJlc3MgdG8gbWFrZSBhIGZpbmFsIGNvbmNsdXNpb24gaWYgaXQgaXMgdHJ1bHkgcmVsYXRlZCB0byBzb21lIGJpb2xvZ2ljYWwgcmVhc29uIG9yIHRlY2huaWNhbC4KCiogUGxvdHRpbmcgY29tcGxleGl0eSBhbmQgZXhhbWluaW5nIGRvbWluYW50IGdlbmVzICh0aGUgZmluYWwgdHJpbyBwbG90cyBiZWxvdyk6CiAgLSBDb21wbGV4aXR5IGJ5IExhcmdlc3QgR2VuZTogICBUaGlzIGlzIHRoZSBzYW1lIGxpbmVhciBwbG90IGFzIGJlZm9yZSwgYnV0IG5vdyB3ZSB2aXN1YWxpemUgdGhlIG1vc3QgZG9taW5hbnQgZ2VuZSBwZXIgY2VsbCAodG9wIDggb3V0IG9mIHRvdGFsIGluIHRoZSBkYXRhc2V0KS4gRG8geW91IHNlZSBhIHBhdHRlcm4gaGVyZSBvciBhIHNwZWNpZmljIGdlbmUgdGhhdCBpcyBleHByZXNzZWQgaW4gbG93IG9yIGhpZ2ggY29tcGxleGl0eSBjZWxscz8gT2Z0ZW4sIHRoZSB1bnVzdWFsIHBvcHVsYXRpb25zIGluIHRoZXNlIHBsb3RzIGNhbiBkZXJpdmUgZnJvbSB0aGUgYWN0aXZpdHkgb2YgYSBzaW5nbGUgZ2VuZSwgc28gbm93IHlvdSBoYXZlIGEgY2hhbmNlIGZpZ3VyZSB0aGlzIG91dC4uLiBJZiB0aGVzZSBnZW5lcyBoYXBwZW4gdG8gYmUgZnJvbSBhIG1pdG9jaG9uZHJpYWwgb3JpZ2luLCB0aGVuIHlvdSBhcmUgbGlrZWx5IGRlYWxpbmcgd2l0aCBkZWFkIGNlbGxzLiBMaWtld2lzZSwgaGlnaCBleHByZXNzaW9uIG9mIE1BTEFUMSBjYW4gYWxzbyBpbmRpY2F0ZSBkZWFkIGNlbGxzLgogIC0gUmVzaWR1YWxzIHZzIFBlcmNlbnRhZ2UgTGFyZ2VzdCBHZW5lczogICAgU2FtZSBhcyBiZWZvcmUsIGJ1dCBub3cgd2l0aCB0aGUgZG9taW5hbnQgZ2VuZSB2aXN1YWxpemVkLiBXaGljaCBnZW5lcyBhcmUgdGhlIGRvbWluYW50IG9uZXMgaW4geW91IG9mZiB0YXJnZXQgcG9wdWxhdGlvbnM/IEFuZCBkb2VzIHRoaXMgbWVldCB5b3VyIGV4cGVjdGF0aW9uPyAgCiAgLSBSZXNpZHVhbHMgdnMgUGVyY2VudGFnZSBMYXJnZXN0IEdlbmVzICsgTVQgJTogICBTYW1lIHBsb3QsIGJ1dCBub3cgd2l0aCBwZXJjZW50YWdlIE1ULiBEbyB0aGUgb2ZmLXRhcmdldCBjZWxsIHBvcHVsYXRpb25zIHNob3cgaGlnaCBwZXJjZW50YWdlIG9mIE1UPyBBbmQgZG8gZmluZCBzb21lIGNvcnJlbGF0aW9uIGJldHdlZW4gdGhpcyBwbG90IGFuZCB0aGUgZG9taW5hbnQgZ2VuZXMgZnJvbSBiZWZvcmUgKE1UIGdlbmVzKT8KYGBge3IgUUMgZ3JhcGggYW5kIGZpbHRlcmluZywgZmlnLmhlaWdodD05LCBmaWcud2lkdGg9MTcsIGVjaG89RkFMU0UsIHdhcm5pbmc9RkFMU0V9CiMjIyMjIyMjIyMjIyMjIyMjIyMjIENodW5rICMjIyMjIyMjIyMjIyMjIyMjIyMjIAojIC8vIFRoaXMgY2h1bmsgcGxvdHMgVmlvbGluIHBsb3Qgd2l0aCB0aGUgZnJlcXVlbmN5IChjZWxscykgYXMgYSBmdW5jdGlvbiBvZiBuR2VuZXMsIG5VTUlzIGFuZCBNVCBwZXJjZW50YWdlCiMgLy8gVGhpcyBjaHVuayBwbG90cyB0aGUgbGluZWFyIHJlbGF0aW9uc2hpcCBvZiBuR2VuZXMgYXMgYSBmdW5jdGlvbiBvZiBuVU1JcyAoYWxzbyBMb2cgc2NhbGVkKSB3aXRoIE1UIHBlcmNlbnRhZ2UgcGVyIGNlbGwKIyAvLyBUaGlzIGNodW5rIHBsb3RzIENvbXBsZXhpdHkgKERlbnNpdHkgdnMgbG9nKGdlbmVzIHBlciBVTUkpKQojIC8vIFRoaXMgY2h1bmsgRmVhdHVyZSBTY2F0dGVycyBjZWxscyB3aXRoIHBlcmNlbnQgTVQgYXMgYSBmdW5jdGlvbiBvZiBuR2VuZXMgYW5kIG5VTUlzCiMjIyMjIyMjIyMjIyMjIyMjIyMjICAgICAgICMjIyMjIyMjIyMjIyMjIyMjIyMjIAoKIyMjIyMjIyMjIyBGdW5jdGlvbiAjIyMjIyMjIyMjIAojIC8vIFRoaXMgZnVuY3Rpb24gcmV0dXJucyB2aW9saW4gcGxvdHMgb2YgIm5GZWF0dXJlX1JOQSIsICJuQ291bnRfUk5BIiwgInBlcmNlbnQubXQiIGZvciBlYWNoIG9iamVjdAojIC8vIFRoaXMgZnVuY3Rpb24gcmV0dXJucyBzY2F0dGVycGxvdHMgb2YgIm5VTUlzIHZzIG5HZW5lcyIsICJQZXJjZW50LU1UIHZzIG5HZW5lcyIsICJQZXJjZW50LU1UIHZzIG5VTUlzIiBmb3IgZWFjaCBvYmplY3QKIyAvLyBJbnB1dCBmaWxlIG11c3QgYmUgYSB2ZWN0b3Igb2YgU2V1cmF0IG9iamVjdHMKZ2V0X3Zpb2xfUUMgPC0gZnVuY3Rpb24oc29iaikgewogIHYxIDwtIFZsblBsb3Qoc29iaiwgZmVhdHVyZXMgPSBjKCJuRmVhdHVyZV9STkEiLCAibkNvdW50X1JOQSIsICJwZXJjZW50Lm10IiksIG5jb2wgPSAzLCBjb2xzID0gIm1hZ2VudGEiKQogIHByaW50KHYxKSAjIFNBVkUgSVQgRk9SIFBJUEUKICAKICBhc190aWJibGUoc29ialtbXV0sIHJvd25hbWVzPSJDZWxsLkJhcmNvZGUiKSAtPiBxYy5tZXRyaWNzICMgc29ial9saXN0W1sxXV1bW11dIHNob3dzIGRhdGEuZnJhbWUgb2YgbWV0YWRhdGEKCiAgcDEgPC0gcWMubWV0cmljcyAlPiUKICAgIGFycmFuZ2UocGVyY2VudC5tdCkgJT4lCiAgICBnZ3Bsb3QoYWVzKG5Db3VudF9STkEsbkZlYXR1cmVfUk5BLCBjb2xvdXI9cGVyY2VudC5tdCkpICsgCiAgICBnZW9tX3BvaW50KCkgKyAKICAgIHNjYWxlX2NvbG91cl9ncmFkaWVudG4oY29sb3VycyA9IGMoJ2JsYWNrJywgJ3JlZDMnLCAncmVkMicpLCB2YWx1ZXMgPSBjKDAsICgoKG1heChzb2JqW1sicGVyY2VudC5tdCJdXSRwZXJjZW50Lm10KSAqIDYpIC8gMTAwKSAvIDEwKSwgMSkpICsKICAgIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDIwMCwgbGluZXR5cGU9ImRhc2hlZCIsIGNvbG9yID0gIm9yYW5nZSIsIHNpemU9MC43KSArCiAgICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSBxdWFudGlsZShzb2JqJG5GZWF0dXJlX1JOQSwgcHJvYj1pZiAoZmVhdHVyZS5xdWFudGlsZS5oaWdoID49IDAgJiBmZWF0dXJlLnF1YW50aWxlLmhpZ2ggPD0gMSAmIGlzLm5hKGZlYXR1cmUucXVhbnRpbGUuaGlnaCkgPT0gRkFMU0Upe2ZlYXR1cmUucXVhbnRpbGUuaGlnaCA9IGZlYXR1cmUucXVhbnRpbGUuaGlnaH1lbHNle2ZlYXR1cmUucXVhbnRpbGUuaGlnaCA9IDAuOTh9KSwgbGluZXR5cGU9ImRhc2hlZCIsIGNvbG9yID0gInllbGxvdyIsIHNpemU9MC43KSArIAogICAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gcXVhbnRpbGUoc29iaiRuRmVhdHVyZV9STkEsIHByb2I9aWYgKGZlYXR1cmUucXVhbnRpbGUubG93ID49IDAgJiBmZWF0dXJlLnF1YW50aWxlLmxvdyA8PSAxICYgaXMubmEoZmVhdHVyZS5xdWFudGlsZS5sb3cpID09IEZBTFNFKXtmZWF0dXJlLnF1YW50aWxlLmxvdyA9IGZlYXR1cmUucXVhbnRpbGUubG93fWVsc2V7ZmVhdHVyZS5xdWFudGlsZS5sb3cgPSAwLjAyfSksIGxpbmV0eXBlPSJkYXNoZWQiLCBjb2xvciA9ICJ5ZWxsb3ciLCBzaXplPTAuNykgKwogICAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gNTUwLCBsaW5ldHlwZT0iZGFzaGVkIiwgY29sb3IgPSAib3JhbmdlIiwgc2l6ZT0wLjcpICsKICAgIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IHF1YW50aWxlKHNvYmokbkNvdW50X1JOQSwgcHJvYj1pZiAoVU1JLnF1YW50aWxlLmhpZ2ggPj0gMCAmIFVNSS5xdWFudGlsZS5oaWdoIDw9IDEgJiBpcy5uYShVTUkucXVhbnRpbGUuaGlnaCkgPT0gRkFMU0Upe1VNSS5xdWFudGlsZS5oaWdoID0gVU1JLnF1YW50aWxlLmhpZ2h9ZWxzZXtVTUkucXVhbnRpbGUuaGlnaCA9IDAuOTh9KSwgbGluZXR5cGU9ImRhc2hlZCIsIGNvbG9yID0gInllbGxvdyIsIHNpemU9MC43KSArCiAgICBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSBxdWFudGlsZShzb2JqJG5Db3VudF9STkEsIHByb2I9aWYgKFVNSS5xdWFudGlsZS5sb3cgPj0gMCAmIFVNSS5xdWFudGlsZS5sb3cgPD0gMSAmIGlzLm5hKFVNSS5xdWFudGlsZS5sb3cpID09IEZBTFNFKXtVTUkucXVhbnRpbGUubG93ID0gVU1JLnF1YW50aWxlLmxvd31lbHNle1VNSS5xdWFudGlsZS5sb3cgPSAwLjAyfSksIGxpbmV0eXBlPSJkYXNoZWQiLCBjb2xvciA9ICJ5ZWxsb3ciLCBzaXplPTAuNykgKwogICAgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxtIiwgY29sb3IgPSAiZ3JlZW4iLCBzaXplPTEpICsgCiAgICBnZ3RpdGxlKHBhc3RlKCJuVU1JcyB2cyBuR2VuZXMgd2l0aCBwZXJjZW50IE1UIiwgc29iakBtZXRhLmRhdGFbMSwxXSwgc2VwID0gIiAtICIpKSArIAogICAgeWxhYigiTnVtYmVyIG9mIEdlbmVzIikgKyAKICAgIHhsYWIoIk51bWJlciBvZiBVTUlzIChSTkEgTW9sZWN1bGVzKSIpICsgCiAgICB0aGVtZV9idygpICsgIyBtYWtlIGZpbGxlciB3aGl0ZQogICAgdGhlbWUocGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfYmxhbmsoKSwgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfYmxhbmsoKSkgIyByZW1vdmUgcmFzdGVyCiAgCiAgcDEuMSA8LSBxYy5tZXRyaWNzICU+JQogICAgYXJyYW5nZShwZXJjZW50Lm10KSAlPiUKICAgIGdncGxvdChhZXMobG9nMTAobkNvdW50X1JOQSksbG9nMTAobkZlYXR1cmVfUk5BKSwgY29sb3VyPXBlcmNlbnQubXQpKSArIAogICAgZ2VvbV9wb2ludCgpICsgCiAgICBzY2FsZV9jb2xvdXJfZ3JhZGllbnRuKGNvbG91cnMgPSBjKCdibGFjaycsICdyZWQzJywgJ3JlZCcpLCB2YWx1ZXMgPSBjKDAsICgoKG1heChzb2JqW1sicGVyY2VudC5tdCJdXSRwZXJjZW50Lm10KSAqIDYpIC8gMTAwKSAvIDEwKSwgMSkpICsKICAgIGdlb21faGxpbmUoeWludGVyY2VwdCA9IGxvZzEwKDIwMCksIGxpbmV0eXBlPSJkYXNoZWQiLCBjb2xvciA9ICJvcmFuZ2UiLCBzaXplPTAuNykgKwogICAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gbG9nMTAocXVhbnRpbGUoc29iaiRuRmVhdHVyZV9STkEsIHByb2I9aWYgKGZlYXR1cmUucXVhbnRpbGUuaGlnaCA+PSAwICYgZmVhdHVyZS5xdWFudGlsZS5oaWdoIDw9IDEgJiBpcy5uYShmZWF0dXJlLnF1YW50aWxlLmhpZ2gpID09IEZBTFNFKXtmZWF0dXJlLnF1YW50aWxlLmhpZ2ggPSBmZWF0dXJlLnF1YW50aWxlLmhpZ2h9ZWxzZXtmZWF0dXJlLnF1YW50aWxlLmhpZ2ggPSAwLjk4fSkpLCBsaW5ldHlwZT0iZGFzaGVkIiwgY29sb3IgPSAieWVsbG93Iiwgc2l6ZT0wLjcpICsgCiAgICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSBsb2cxMChxdWFudGlsZShzb2JqJG5GZWF0dXJlX1JOQSwgcHJvYj1pZiAoZmVhdHVyZS5xdWFudGlsZS5sb3cgPj0gMCAmIGZlYXR1cmUucXVhbnRpbGUubG93IDw9IDEgJiBpcy5uYShmZWF0dXJlLnF1YW50aWxlLmxvdykgPT0gRkFMU0Upe2ZlYXR1cmUucXVhbnRpbGUubG93ID0gZmVhdHVyZS5xdWFudGlsZS5sb3d9ZWxzZXtmZWF0dXJlLnF1YW50aWxlLmxvdyA9IDAuMDJ9KSksIGxpbmV0eXBlPSJkYXNoZWQiLCBjb2xvciA9ICJ5ZWxsb3ciLCBzaXplPTAuNykgKwogICAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gbG9nMTAoNTUwKSwgbGluZXR5cGU9ImRhc2hlZCIsIGNvbG9yID0gIm9yYW5nZSIsIHNpemU9MC43KSArCiAgICBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSBsb2cxMChxdWFudGlsZShzb2JqJG5Db3VudF9STkEsIHByb2I9aWYgKFVNSS5xdWFudGlsZS5oaWdoID49IDAgJiBVTUkucXVhbnRpbGUuaGlnaCA8PSAxICYgaXMubmEoVU1JLnF1YW50aWxlLmhpZ2gpID09IEZBTFNFKXtVTUkucXVhbnRpbGUuaGlnaCA9IFVNSS5xdWFudGlsZS5oaWdofWVsc2V7VU1JLnF1YW50aWxlLmhpZ2ggPSAwLjk4fSkpLCBsaW5ldHlwZT0iZGFzaGVkIiwgY29sb3IgPSAieWVsbG93Iiwgc2l6ZT0wLjcpICsKICAgIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IGxvZzEwKHF1YW50aWxlKHNvYmokbkNvdW50X1JOQSwgcHJvYj1pZiAoVU1JLnF1YW50aWxlLmxvdyA+PSAwICYgVU1JLnF1YW50aWxlLmxvdyA8PSAxICYgaXMubmEoVU1JLnF1YW50aWxlLmxvdykgPT0gRkFMU0Upe1VNSS5xdWFudGlsZS5sb3cgPSBVTUkucXVhbnRpbGUubG93fWVsc2V7VU1JLnF1YW50aWxlLmxvdyA9IDAuMDJ9KSksIGxpbmV0eXBlPSJkYXNoZWQiLCBjb2xvciA9ICJ5ZWxsb3ciLCBzaXplPTAuNykgKwogICAgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxtIiwgY29sb3IgPSAiZ3JlZW4iLCBzaXplPTEpICsgCiAgICBnZ3RpdGxlKHBhc3RlKCJMb2cxMCBzY2FsZWQ6IG5VTUlzIHZzIG5HZW5lcyB3aXRoIHBlcmNlbnQgTVQiKSkgKyAKICAgIHlsYWIoIkxvZzEwIChOdW1iZXIgb2YgR2VuZXMpIikgKyAKICAgIHhsYWIoIkxvZzEwIChOdW1iZXIgb2YgVU1JcykiKSArIAogICAgdGhlbWVfYncoKSArICMgbWFrZSBmaWxsZXIgd2hpdGUKICAgIHRoZW1lKHBhbmVsLmdyaWQubWFqb3IgPSBlbGVtZW50X2JsYW5rKCksIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2JsYW5rKCkpICAjIHJlbW92ZSByYXN0ZXIKICAKICAjIEFkZCBudW1iZXIgb2YgZ2VuZXMgcGVyIFVNSSBmb3IgZWFjaCBjZWxsIHRvIG1ldGFkYXRhCiAgc29iaiRsb2cxMEdlbmVzUGVyVU1JIDwtIGxvZzEwKHNvYmokbkZlYXR1cmVfUk5BKSAvIGxvZzEwKHNvYmokbkNvdW50X1JOQSkKICAjIFZpc3VhbGl6ZSB0aGUgb3ZlcmFsbCBjb21wbGV4aXR5IG9mIHRoZSBnZW5lIGV4cHJlc3Npb24gYnkgdmlzdWFsaXppbmcgdGhlIGdlbmVzIGRldGVjdGVkIHBlciBVTUkKICBwMS4yIDwtIHNvYmpAbWV0YS5kYXRhICU+JQogIAlnZ3Bsb3QoYWVzKGxvZzEwR2VuZXNQZXJVTUkpKSArCiAgCWdlb21fZGVuc2l0eShhbHBoYSA9IDEsIGNvbG9yID0gIm9yYW5nZSIsIHNpemU9MS41KSArCiAgCXRoZW1lX2NsYXNzaWMoKSArCiAgCWdlb21fdmxpbmUoeGludGVyY2VwdCA9IDAuOCwgbGluZXR5cGU9ImRhc2hlZCIsIGNvbG9yID0gInJlZCIsIHNpemU9MSkgKwogICAgZ2d0aXRsZShwYXN0ZSgiQ29tcGxleGl0eSBQbG90OiIsIHNvYmpAbWV0YS5kYXRhWzEsMV0sIHNlcCA9ICIgIikpICsgCiAgICB5bGFiKCJEZW5zaXR5IikgKyAKICAgIHhsYWIoIkxvZzEwIEdlbmVzL1VNSSAoR2VuZXMgcGVyIFVNSSkiKQogIAogICAgICMgT0xEIFVNSSB2cyBHZW5lIHBsb3QKIyAgICBwMSA8LSBGZWF0dXJlU2NhdHRlcihzb2JqLCBmZWF0dXJlMSA9ICJuQ291bnRfUk5BIiwgZmVhdHVyZTIgPSAibkZlYXR1cmVfUk5BIiAsIGNvbHMgPSAiYmxhY2siLCApICsgCiMgICAgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxtIikgKyBnZ3RpdGxlKHBhc3RlKCJuVU1JcyB2cyBuR2VuZXMiLCBzb2JqQG1ldGEuZGF0YVsxLDFdLCBzZXAgPSAiIC0gIikpICsgCiMgICAgeWxhYigiTnVtYmVyIG9mIEdlbmVzIikgKyAKIyAgICB4bGFiKCJOdW1iZXIgb2YgVU1JcyAoUk5BIE1vbGVjdWxlcykiKSArIE5vTGVnZW5kKCkKICAKICAKICAjIExldCB0YWtlIGEgY2xvc2VyIGxvb2sgYXQgdGhlIGNvbXBsZXhpdHkgb2YgdGhlIGRhdGEgYW5kIGRyaXZlbiBieSB3aGF0IGdlbmUuIAogICMgQ2FsY3VsYXRlIGNhbGN1bGF0ZSB0aGUgbG9nMTAobkZlYXR1cmVfUk5BKSAvIGxvZzEwKG5Db3VudF9STkEpKSBhbmQgcHV0IGluIHRoZSBxYy5tZXRyaWMKICBxYy5tZXRyaWNzICU+JQogIGRwbHlyOjptdXRhdGUoY29tcGxleGl0eT1sb2cxMChuRmVhdHVyZV9STkEpIC8gbG9nMTAobkNvdW50X1JOQSkpICAtPiBxYy5tZXRyaWNzCiAgIyBNYWtlIGxpbmVhciBtb2RlbHMgb2YgbG9nMTAobkZlYXV0dXJlcykgdnMgTG9nMTAoblVNSXMpIGFuZCBwdXQgaW4gcHV0IGluIGNvbXBsZXhpdHkubG0KICAjIEhlcmUsIHdlIGNhbGN1bGF0ZSB0aGUgZGlmZmVyZW5jZSBmcm9tIHRoZSBvYnNlcnZlZCB2YWx1ZSB0byB0aGUgZXhwZWN0ZWQKICBsbShsb2cxMChxYy5tZXRyaWNzJG5GZWF0dXJlX1JOQSl+bG9nMTAocWMubWV0cmljcyRuQ291bnRfUk5BKSkgLT4gY29tcGxleGl0eS5sbQogICMgQ2FsY3VsYXRlIHRoZSBjb21wbGV4aXR5IGZyb20gdGhlIG1pZGRsZSBsaW5lIG9mIHRoZSBsaW5lYXIgbW9kZWwKICAjIFdlIHdpbGwgdXNlIHRoaXMgZm9yIHRoZSBjb2xvciBzY2FsZSBvZiB0aGUgZ3JhcGggYXMgd2VsbC4KICBxYy5tZXRyaWNzICU+JQogIGRwbHlyOjptdXRhdGUoY29tcGxleGl0eV9kaWZmID0gbG9nMTAobkZlYXR1cmVfUk5BKSAtICgobG9nMTAocWMubWV0cmljcyRuQ291bnRfUk5BKSpjb21wbGV4aXR5LmxtJGNvZWZmaWNpZW50c1syXSkrY29tcGxleGl0eS5sbSRjb2VmZmljaWVudHNbMV0pCiAgKSAtPiBxYy5tZXRyaWNzCiAgIyBGaW5kIHRoZSBkZWx0YSBkaWZmZXJlbmNlIGZvciB0aGUgZ3JhcGgKICBtaW4oYyhtYXgocWMubWV0cmljcyRjb21wbGV4aXR5X2RpZmYpLDAtbWluKHFjLm1ldHJpY3MkY29tcGxleGl0eV9kaWZmKSkpIC0+IGNvbXBsZXhpdHlfc2NhbGUKCiAgIyBIZXJlIHdlIHZpc3VhbGl6ZSB0aGUgdGhlIGRhdGEgY29tcGxleGl0eSAoY2VsbHMpIGJhc2VkIG9uIHRoZSBjYWxjdWxhdGlvbnMgYWJvdmUKICBwMS4zIDwtIHFjLm1ldHJpY3MgJT4lIAogIGRwbHlyOjptdXRhdGUoY29tcGxleGl0eV9kaWZmPXJlcGxhY2UoY29tcGxleGl0eV9kaWZmLGNvbXBsZXhpdHlfZGlmZjwgLTAuNSwtMC41KSkgJT4lCiAgZ2dwbG90KGFlcyh4PWxvZzEwKG5Db3VudF9STkEpLCB5PWxvZzEwKG5GZWF0dXJlX1JOQSksIGNvbG91cj1jb21wbGV4aXR5X2RpZmYpKSArCiAgZ2VvbV9wb2ludCgpICsKICBnZW9tX2FibGluZShzbG9wZT1jb21wbGV4aXR5LmxtJGNvZWZmaWNpZW50c1syXSwgaW50ZXJjZXB0ID0gY29tcGxleGl0eS5sbSRjb2VmZmljaWVudHNbMV0pICsKICBzY2FsZV9jb2xvdXJfZ3JhZGllbnQyKGxvdz0iYmx1ZTIiLG1pZD0iZ3JleSIsaGlnaD0icmVkMiIpICsKICBnZ3RpdGxlKHBhc3RlKCJDb21wbGV4aXR5OiBMb2cxMCAtIG5VTUlzIHZzIG5HZW5lcyIsIHNvYmpAbWV0YS5kYXRhWzEsMV0sIHNlcCA9ICIgLSAiKSkgKyAKICB5bGFiKCJMb2cxMCAoTnVtYmVyIG9mIEdlbmVzKSIpICsgCiAgeGxhYigiTG9nMTAgKE51bWJlciBvZiBVTUlzKSIpICsgCiAgdGhlbWVfYncoKSArIAogIHRoZW1lKHBhbmVsLmdyaWQubWFqb3IgPSBlbGVtZW50X2JsYW5rKCksIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2JsYW5rKCkpCgogICMgSGVyZSB3ZSB2aXN1YWxpemUgdGhlIGRlbnNpdHkgcGxvdCBvZiB0aGUgY2VsbHMgZnJvbSB0aGUgbWlkZGxlIG9mIHRoZSBsaW5lYXIgZ3JhcGggZnJvbSBQMS4zCiAgcDEuNCA8LSBxYy5tZXRyaWNzICU+JSBnZ3Bsb3QoYWVzKHg9Y29tcGxleGl0eV9kaWZmKSkgKyAKICBnZW9tX2RlbnNpdHkoZmlsbD0ieWVsbG93IikgKwogIGdndGl0bGUocGFzdGUoIlJlc2lkdWFsIHZzIERlbnNpdHkiKSkgKyAKICB5bGFiKCJEZW5zaXR5IikgKyAKICB4bGFiKCJDb21wbGV4aXR5IERpZmZlcmVuY2UgKFJlc2lkdWFscykiKSArIAogIHRoZW1lX2J3KCkgKyAKICB0aGVtZShwYW5lbC5ncmlkLm1ham9yID0gZWxlbWVudF9ibGFuaygpLCBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9ibGFuaygpKQogIAogICMgTm93IGxldHMgd2hpY2ggZ2VuZXMgYXJlIGFjdHVhbGx5IGRyaXZpbmcgdGhlIGxvdyBjb21wbGV4aXR5IGNlbGxzIGluIHRoZSBkYXRhCiAgIyBGb3IgdGhpcywgd2UgZmlyc3QgY2FsY3VsYXRlIHRoZSBwZXJjZW50YWdlIG9mIGxhcmdlc3QgZ2VuZXMuCiAgIyBGaW5kIHRoZSBjZWxscyB3aXRoIGxhcmdlc3QgY291bnRzCiAgcWMubWV0cmljcyAlPiUgbXV0YXRlKGxhcmdlc3RfY291bnQgPSBhcHBseShzb2JqQGFzc2F5cyRSTkFAbGF5ZXJzJGNvdW50cywgMiwgbWF4KSkgLT4gcWMubWV0cmljcyAjICIyIiBpcyB0byByZXR1cm4gbWF4IGNvbHVtbnMgdmFsdWVzCiAgIyBmaW5kIHRoZSBpbmRleCBvZiB0aGUgY2VsbCB3aXRoIGxhcmdlc3QgY291bnRzCiAgcWMubWV0cmljcyAlPiUgbXV0YXRlKGxhcmdlc3RfaW5kZXggPSBhcHBseShzb2JqQGFzc2F5cyRSTkFAbGF5ZXJzJGNvdW50cywgMiwgd2hpY2gubWF4KSkgLT4gcWMubWV0cmljcwogICMgVXNlIHRoZSBpbmRleCBhbmQgZ2V0IHRoZSBnZW5lIG5hbWUgdGhhdCBhY2NvdW50cyBmb3IgdGhlIGxhcmdlc3QgY291bnRzIHBlciBjZWxsCiAgcWMubWV0cmljcyAlPiUgbXV0YXRlKGxhcmdlc3RfZ2VuZSA9IHJvd25hbWVzKHNvYmopW2xhcmdlc3RfaW5kZXhdKSAtPiBxYy5tZXRyaWNzCiAgIyBOb3cgY2FsY3VsYXRlIHRoZSBwZXJjZW50YWdlIHJlbGF0aXZlIHRvIHRoZSB0b3RhbCBjb3VudHMgaW4gdGhlIGRhdGEKICBxYy5tZXRyaWNzICU+JSBtdXRhdGUocGVyY2VudC5MYXJnZXN0LkdlbmUgPSAgMTAwICogbGFyZ2VzdF9jb3VudCAvIG5Db3VudF9STkEpIC0+IHFjLm1ldHJpY3MKICAKICAjIFZpc3VhbGl6ZSB0aGUgY29tcGxleGl0eSBleHBsYWluZWQgYnkgcGVyY2VudGFnZSBvZiBsYXJnZXN0IGdlbmVzCiAgcDEuNSA8LSBxYy5tZXRyaWNzICU+JSBnZ3Bsb3QoYWVzKHg9Y29tcGxleGl0eV9kaWZmLCB5PXBlcmNlbnQuTGFyZ2VzdC5HZW5lKSkgKyAKICAgIGdlb21fcG9pbnQoKSArCiAgICBnZ3RpdGxlKHBhc3RlKCJSZXNpZHVhbHMgdnMgUGVyY2VudGFnZSBMYXJnZXN0IEdlbmVzIikpICsgCiAgICB5bGFiKCJQZXJjZW50YWdlIExhcmdlc3QgR2VuZSAoJSkiKSArIAogICAgeGxhYigiQ29tcGxleGl0eSBEaWZmZXJlbmNlIChSZXNpZHVhbHMpIikgKyAKICAgIHRoZW1lX2J3KCkgKyAKICAgIHRoZW1lKHBhbmVsLmdyaWQubWFqb3IgPSBlbGVtZW50X2JsYW5rKCksIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2JsYW5rKCkpCiAgCiAgIyBTb3J0IHRoZSBwZXJjZW50YWdlIGxhcmdlc3QgZ2VuZXMgCiAgcWMubWV0cmljcyAlPiUKICBkcGx5cjo6Z3JvdXBfYnkobGFyZ2VzdF9nZW5lKSAlPiUgZHBseXI6OmFycmFuZ2UoZGVzYyhwZXJjZW50Lkxhcmdlc3QuR2VuZSkpIC0+IGxhcmdlc3RfZ2VuZV9saXN0CiAgIyBGaWx0ZXIgb3V0IHRoZSBnZW5lcyA+NSUgY291bnRzIAogIGxhcmdlc3RfZ2VuZV9saXN0ICU+JQogIGRwbHlyOjpmaWx0ZXIocGVyY2VudC5MYXJnZXN0LkdlbmUgPiAwLjUpICU+JSAjIGZpbHRlciBleGlzdHMgaW4gb3RoZXIgcGFja2FnZXMsIHVzZSBkcGx5cjo6IHRvIGZpeAogIGRwbHlyOjpwdWxsKGxhcmdlc3RfZ2VuZSkgLT4gbGFyZ2VzdF9nZW5lc190b19wbG90CiAgbGFyZ2VzdF9nZW5lc190b19wbG90IDwtIHVuaXF1ZShsYXJnZXN0X2dlbmVzX3RvX3Bsb3QpWzE6OF0gIyBSZW1vdmUgZHVwbGljYXRlZCBnZW5lIG5hbWVzIGFuZCB0YWtlIHVwIHRvIDEwIGdlbmVzCiAgCiAgIyBQbG90IHRoZSBsaW5lYXIgY29tcGxleGl0eSBtb2RlbCB0aGF0IGV4cGxhaW4gdGhlIGRldmlhdGlvbiBieSB0aGUgbGFyZ2VzdCBnZW5lcwogIHAxLjYgPC0gcWMubWV0cmljcyAlPiUKICBkcGx5cjo6ZmlsdGVyKGxhcmdlc3RfZ2VuZSAlaW4lIGxhcmdlc3RfZ2VuZXNfdG9fcGxvdCkgJT4lCiAgZHBseXI6Om11dGF0ZShsYXJnZXN0X2dlbmU9ZmFjdG9yKGxhcmdlc3RfZ2VuZSwgbGV2ZWxzPWxhcmdlc3RfZ2VuZXNfdG9fcGxvdCkpICU+JQogIGRwbHlyOjphcnJhbmdlKGxhcmdlc3RfZ2VuZSkgJT4lCiAgZ2dwbG90KGFlcyh4PWxvZzEwKG5Db3VudF9STkEpLCB5PWxvZzEwKG5GZWF0dXJlX1JOQSksIGNvbG91cj1sYXJnZXN0X2dlbmUpKSArCiAgZ2VvbV9wb2ludChzaXplPTEuNSkgKwogIGdlb21fYWJsaW5lKHNsb3BlPWNvbXBsZXhpdHkubG0kY29lZmZpY2llbnRzWzJdLCBpbnRlcmNlcHQgPSBjb21wbGV4aXR5LmxtJGNvZWZmaWNpZW50c1sxXSkgKyAjaW1wb3J0IHRoZSBsaW5lIGZvcm0gbGluZWFyIG1vZGVsIGZyb20gYmVmb3JlCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gbG9nMTAoMjAwKSwgbGluZXR5cGU9ImRhc2hlZCIsIGNvbG9yID0gIm9yYW5nZSIsIHNpemU9MC43KSArCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gbG9nMTAocXVhbnRpbGUoc29iaiRuRmVhdHVyZV9STkEsIHByb2I9aWYgKGZlYXR1cmUucXVhbnRpbGUuaGlnaCA+PSAwICYgZmVhdHVyZS5xdWFudGlsZS5oaWdoIDw9IDEgJiBpcy5uYShmZWF0dXJlLnF1YW50aWxlLmhpZ2gpID09IEZBTFNFKXtmZWF0dXJlLnF1YW50aWxlLmhpZ2ggPSBmZWF0dXJlLnF1YW50aWxlLmhpZ2h9ZWxzZXtmZWF0dXJlLnF1YW50aWxlLmhpZ2ggPSAwLjk4fSkpLCBsaW5ldHlwZT0iZGFzaGVkIiwgY29sb3IgPSAieWVsbG93Iiwgc2l6ZT0wLjcpICsgCiAgICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSBsb2cxMChxdWFudGlsZShzb2JqJG5GZWF0dXJlX1JOQSwgcHJvYj1pZiAoZmVhdHVyZS5xdWFudGlsZS5sb3cgPj0gMCAmIGZlYXR1cmUucXVhbnRpbGUubG93IDw9IDEgJiBpcy5uYShmZWF0dXJlLnF1YW50aWxlLmxvdykgPT0gRkFMU0Upe2ZlYXR1cmUucXVhbnRpbGUubG93ID0gZmVhdHVyZS5xdWFudGlsZS5sb3d9ZWxzZXtmZWF0dXJlLnF1YW50aWxlLmxvdyA9IDAuMDJ9KSksIGxpbmV0eXBlPSJkYXNoZWQiLCBjb2xvciA9ICJ5ZWxsb3ciLCBzaXplPTAuNykgKwogICAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gbG9nMTAoNTUwKSwgbGluZXR5cGU9ImRhc2hlZCIsIGNvbG9yID0gIm9yYW5nZSIsIHNpemU9MC43KSArCiAgICBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSBsb2cxMChxdWFudGlsZShzb2JqJG5Db3VudF9STkEsIHByb2I9aWYgKFVNSS5xdWFudGlsZS5oaWdoID49IDAgJiBVTUkucXVhbnRpbGUuaGlnaCA8PSAxICYgaXMubmEoVU1JLnF1YW50aWxlLmhpZ2gpID09IEZBTFNFKXtVTUkucXVhbnRpbGUuaGlnaCA9IFVNSS5xdWFudGlsZS5oaWdofWVsc2V7VU1JLnF1YW50aWxlLmhpZ2ggPSAwLjk4fSkpLCBsaW5ldHlwZT0iZGFzaGVkIiwgY29sb3IgPSAieWVsbG93Iiwgc2l6ZT0wLjcpICsKICAgIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IGxvZzEwKHF1YW50aWxlKHNvYmokbkNvdW50X1JOQSwgcHJvYj1pZiAoVU1JLnF1YW50aWxlLmxvdyA+PSAwICYgVU1JLnF1YW50aWxlLmxvdyA8PSAxICYgaXMubmEoVU1JLnF1YW50aWxlLmxvdykgPT0gRkFMU0Upe1VNSS5xdWFudGlsZS5sb3cgPSBVTUkucXVhbnRpbGUubG93fWVsc2V7VU1JLnF1YW50aWxlLmxvdyA9IDAuMDJ9KSksIGxpbmV0eXBlPSJkYXNoZWQiLCBjb2xvciA9ICJ5ZWxsb3ciLCBzaXplPTAuNykgKwogICAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXM9YygiZ3JleSIsUkNvbG9yQnJld2VyOjpicmV3ZXIucGFsKDksIlNldDEiKSkpICsKICBnZ3RpdGxlKHBhc3RlKCJDb21wbGV4aXR5IGJ5IExhcmdlc3QgR2VuZSIsIHNvYmpAbWV0YS5kYXRhWzEsMV0sIHNlcCA9ICIgLSAiKSkgKyAKICB5bGFiKCJMb2cxMCAoTnVtYmVyIG9mIEdlbmVzKSIpICsgCiAgeGxhYigiTG9nMTAgKE51bWJlciBvZiBVTUlzKSIpICsgCiAgdGhlbWVfYncoKSArIAogIHRoZW1lKHBhbmVsLmdyaWQubWFqb3IgPSBlbGVtZW50X2JsYW5rKCksIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2JsYW5rKCkpIAogICAgCiAgIyBOb3cgcGxvdCBhIHNjYXR0ZXIgb2YgdGhlIGNlbGxzIHdpdGggdGhlIHJlc2lkdWFscyBvbiB0aGUgeC1heGlzIGFuZCBwZXJjZW50YWdlIGxhcmdlc3QgZ2VuZSBpbiB0aGUgeS1heGlzCiAgcDEuNyA8LSBxYy5tZXRyaWNzICU+JQogIGRwbHlyOjpmaWx0ZXIobGFyZ2VzdF9nZW5lICVpbiUgbGFyZ2VzdF9nZW5lc190b19wbG90KSAlPiUKICBkcGx5cjo6bXV0YXRlKGxhcmdlc3RfZ2VuZT1mYWN0b3IobGFyZ2VzdF9nZW5lLCBsZXZlbHM9bGFyZ2VzdF9nZW5lc190b19wbG90KSkgJT4lCiAgZHBseXI6OmFycmFuZ2UobGFyZ2VzdF9nZW5lKSAlPiUKICBnZ3Bsb3QoYWVzKHg9Y29tcGxleGl0eV9kaWZmLCB5PXBlcmNlbnQuTGFyZ2VzdC5HZW5lLCBjb2xvdXI9bGFyZ2VzdF9nZW5lKSkgKwogIGdlb21fcG9pbnQoc2l6ZT0xLjUpICsKICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcz1jKCJncmV5IixSQ29sb3JCcmV3ZXI6OmJyZXdlci5wYWwoOSwiU2V0MSIpKSkgKyAKICBnZ3RpdGxlKHBhc3RlKCJSZXNpZHVhbCB2cyBQZXJjZW50YWdlIExhcmdlc3QgR2VuZXMiKSkgKyAKICB5bGFiKCJQZXJjZW50YWdlIExhcmdlc3QgR2VuZSAoJSkiKSArIAogIHhsYWIoIkNvbXBsZXhpdHkgRGlmZmVyZW5jZSAoUmVzaWR1YWxzKSIpICsgCiAgdGhlbWVfYncoKSArIAogIHRoZW1lKHBhbmVsLmdyaWQubWFqb3IgPSBlbGVtZW50X2JsYW5rKCksIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2JsYW5rKCkpCiAgCiAgIyBTYW1lIGFzIGFib3ZlLCBidXQgbm93IHdpdGggcGVyY2VudGFnZS5NVCBhcyBncmFkaWVudAogIHAxLjggPC0gcWMubWV0cmljcyAlPiUKICBhcnJhbmdlKHBlcmNlbnQubXQpICU+JQogIGdncGxvdChhZXMoeD1jb21wbGV4aXR5X2RpZmYsIHk9cGVyY2VudC5MYXJnZXN0LkdlbmUsIGNvbG91cj1wZXJjZW50Lm10KSkgKwogIGdlb21fcG9pbnQoKSArCiAgc2NhbGVfY29sb3VyX2dyYWRpZW50bihjb2xvdXJzID0gYygnYmxhY2snLCAncmVkMycsICdyZWQyJyksIHZhbHVlcyA9IGMoMCwgKCgobWF4KHNvYmpbWyJwZXJjZW50Lm10Il1dJHBlcmNlbnQubXQpICogNikgLyAxMDApIC8gMTApLCAxKSkgKwogIGdndGl0bGUocGFzdGUoIlJlc2lkdWFscyB2cyBQZXJjZW50YWdlIExhcmdlc3QgR2VuZXMgKyBNVCAlIikpICsgCiAgeWxhYigiUGVyY2VudGFnZSBMYXJnZXN0IEdlbmUgKCUpIikgKyAKICB4bGFiKCJDb21wbGV4aXR5IERpZmZlcmVuY2UgKFJlc2lkdWFscykiKSArIAogIHRoZW1lX2J3KCkgKyAKICB0aGVtZShwYW5lbC5ncmlkLm1ham9yID0gZWxlbWVudF9ibGFuaygpLCBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9ibGFuaygpKSAgIAogIAogICMgVmlzdWFsaXplIHRoZSByZWxhdGlvbnNoaXAgYmV0d2VlbiAlTVQgdnMgbkdlbmVzIG5hZCBuVU1JcwogIHAyIDwtIEZlYXR1cmVTY2F0dGVyKHNvYmosIGZlYXR1cmUxID0gIm5GZWF0dXJlX1JOQSIsIGZlYXR1cmUyID0gInBlcmNlbnQubXQiLCBjb2xzID0gImJsYWNrIikgKyAKICAgIGdndGl0bGUocGFzdGUoIlBlcmNlbnQtTVQgdnMgbkdlbmVzIiwgc29iakBtZXRhLmRhdGFbMSwxXSwgc2VwID0gIiAtICIpKSArIAogICAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gMTAsIGxpbmV0eXBlPSJkYXNoZWQiLCBjb2xvciA9ICJyZWQiLCBzaXplPTEpICsKICAgIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDcuNSwgbGluZXR5cGU9ImRhc2hlZCIsIGNvbG9yID0gIm9yYW5nZSIsIHNpemU9MSkgKyAKICAgIHlsYWIoIlBlcmNlbnQgTXRpb2Nob25kcmlhbCBHZW5lcyAoJSkiKSArIAogICAgeGxhYigiTnVtYmVyIG9mIEdlbmVzIikgKyBOb0xlZ2VuZCgpICsgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpKQogIHAzIDwtIEZlYXR1cmVTY2F0dGVyKHNvYmosIGZlYXR1cmUxID0gIm5Db3VudF9STkEiLCBmZWF0dXJlMiA9ICJwZXJjZW50Lm10IiwgY29scyA9ICJibGFjayIpICsgCiAgICBnZ3RpdGxlKHBhc3RlKCJQZXJjZW50LU1UIHZzIG5VTUlzIikpICsgCiAgICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSAxMCwgbGluZXR5cGU9ImRhc2hlZCIsIGNvbG9yID0gInJlZCIsIHNpemU9MSkgKwogICAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gNy41LCBsaW5ldHlwZT0iZGFzaGVkIiwgY29sb3IgPSAib3JhbmdlIiwgc2l6ZT0xKSArIAogICAgeWxhYigiUGVyY2VudCBNdGlvY2hvbmRyaWFsIEdlbmVzICglKSIpICsgCiAgICB4bGFiKCJOdW1iZXIgb2YgVU1JcyAoUk5BIE1vbGVjdWxlcykiKSArIE5vTGVnZW5kKCkgKyB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSkpCiAgCiAgIyBQcmludCBwbG90cwogIHByaW50KHAyICsgcDMpCiAgcHJpbnQocDEgKyBwMS4xKSAjIG9yIFNBVkUKICBwcmludChwMS4yKQogIHByaW50KHAxLjMgKyBwMS40ICsgcDEuNSkKICBwcmludChwMS42ICsgcDEuNyArIHAxLjgpCiAgcmV0dXJuKCkKfQojIEFwcGx5IGZ1bmN0aW9uIGdldF92aW9sX1FDCnZpb2wgPC0gc2FwcGx5KHNvYmpfbGlzdCwgZ2V0X3Zpb2xfUUMpCgojIEZpbmQgdGhlIHVwcGVyIHF1YW50aWxlIGFibGluZXMgZm9yIFVNSSBhbmQgbkZlYXR1cmVzIHRoYXQgd2Ugd2FudCB0byBwbG90IGxhdGVyIGluIHRoZSBmaW5hbCBncmFwaHMKIyBUaGVzZSBhcmUgdGhlIHF1YW50aWxlcyBvZiB0aGUgdW5maWx0ZXJlZCBkYXRhClVNSS5xdWFudGlsZS5hYmxpbmUgPC0gYygpCmZlYXR1cmUucXVhbnRpbGUuYWJsaW5lIDwtIGMoKQpVTUkucXVhbnRpbGUuYWJsaW5lLmxvdyA8LSBjKCkKZmVhdHVyZS5xdWFudGlsZS5hYmxpbmUubG93IDwtIGMoKQpmb3IgKGkgaW4gMTpsZW5ndGgoeCA9IHNvYmpfbGlzdCkpIHsKICBpZiAoVU1JLnF1YW50aWxlLmhpZ2ggPj0gMCAmIFVNSS5xdWFudGlsZS5oaWdoIDw9IDEgJiBpcy5uYShVTUkucXVhbnRpbGUuaGlnaCkgPT0gRkFMU0UpIHsKICAgIFVNSS5xdWFudGlsZS5hYmxpbmVbaV0gPC0gcXVhbnRpbGUoc29ial9saXN0W1tpXV0kbkNvdW50X1JOQSwgcHJvYj1VTUkucXVhbnRpbGUuaGlnaCkKICB9IGVsc2UgeyAKICAgIFVNSS5xdWFudGlsZS5hYmxpbmVbaV0gPC0gcXVhbnRpbGUoc29ial9saXN0W1tpXV0kbkNvdW50X1JOQSwgcHJvYj0wLjk4KQogICAgfQogIGlmIChmZWF0dXJlLnF1YW50aWxlLmhpZ2ggPj0gMCAmIGZlYXR1cmUucXVhbnRpbGUuaGlnaCA8PSAxICYgaXMubmEoZmVhdHVyZS5xdWFudGlsZS5oaWdoKSA9PSBGQUxTRSkgewogICAgZmVhdHVyZS5xdWFudGlsZS5hYmxpbmVbaV0gPC0gcXVhbnRpbGUoc29ial9saXN0W1tpXV0kbkZlYXR1cmVfUk5BLCBwcm9iPWZlYXR1cmUucXVhbnRpbGUuaGlnaCkKICB9IGVsc2UgeyAKICAgIGZlYXR1cmUucXVhbnRpbGUuYWJsaW5lW2ldIDwtIHF1YW50aWxlKHNvYmpfbGlzdFtbaV1dJG5GZWF0dXJlX1JOQSwgcHJvYj0wLjk4KQogIH0KICBpZiAoVU1JLnF1YW50aWxlLmxvdyA+PSAwICYgVU1JLnF1YW50aWxlLmxvdyA8PSAxICYgaXMubmEoVU1JLnF1YW50aWxlLmxvdykgPT0gRkFMU0UpIHsKICAgIFVNSS5xdWFudGlsZS5hYmxpbmUubG93W2ldIDwtIHF1YW50aWxlKHNvYmpfbGlzdFtbaV1dJG5Db3VudF9STkEsIHByb2I9VU1JLnF1YW50aWxlLmxvdykKICB9IGVsc2UgeyAKICAgIFVNSS5xdWFudGlsZS5hYmxpbmUubG93W2ldIDwtIHF1YW50aWxlKHNvYmpfbGlzdFtbaV1dJG5Db3VudF9STkEsIHByb2I9MC4wMikKICB9CiAgaWYgKGZlYXR1cmUucXVhbnRpbGUubG93ID49IDAgJiBmZWF0dXJlLnF1YW50aWxlLmxvdyA8PSAxICYgaXMubmEoZmVhdHVyZS5xdWFudGlsZS5sb3cpID09IEZBTFNFKSB7CiAgICBmZWF0dXJlLnF1YW50aWxlLmFibGluZS5sb3dbaV0gPC0gcXVhbnRpbGUoc29ial9saXN0W1tpXV0kbkZlYXR1cmVfUk5BLCBwcm9iPWZlYXR1cmUucXVhbnRpbGUubG93KQogIH0gZWxzZSB7IAogICAgZmVhdHVyZS5xdWFudGlsZS5hYmxpbmUubG93W2ldIDwtIHF1YW50aWxlKHNvYmpfbGlzdFtbaV1dJG5GZWF0dXJlX1JOQSwgcHJvYj0wLjAyKQogIH0KfQoKIyMjIyMjIyMjIyMjIFNFQ09ORCBXQVkgVE8gRE8gSVQsIEZPUiBTQVZJTkcgSU1BR0VTICMjIyMjIyMjIyMjIyMjCiNmb3IgKGkgaW4gMTpsZW5ndGgoeCA9IHNvYmpfbGlzdCkpIHsKIyAgdjEgPC0gVmxuUGxvdChzb2JqX2xpc3RbW2ldXSwgZmVhdHVyZXMgPSBjKCJuRmVhdHVyZV9STkEiLCAibkNvdW50X1JOQSIsICJwZXJjZW50Lm10IiksIG5jb2wgPSAzKQojICBwcmludCh2MSkgIyBTQVZFIElUIEZPUiBQSVBFCiAgCiMgIHAxIDwtIEZlYXR1cmVTY2F0dGVyKHNvYmpfbGlzdFtbaV1dLCBmZWF0dXJlMSA9ICJuQ291bnRfUk5BIiwgZmVhdHVyZTIgPSAibkZlYXR1cmVfUk5BIiwgY29scyA9ICJibGFjayIsICkgKyBnZW9tX3Ntb290aChtZXRob2QgPSAibG0iKSArIGdndGl0bGUocGFzdGUoIm5VTUlzIHZzIG5HZW5lcyIsIHNvYmpfbGlzdFtbaV1dQG1ldGEuZGF0YVsxLDFdLCBzZXAgPSAiIC0gIikpICsgeWxhYigiTnVtYmVyIG9mIEdlbmVzIikgKyB4bGFiKCJOdW1iZXIgb2YgVU1JcyAoUk5BIE1vbGVjdWxlcykiKSArIE5vTGVnZW5kKCkKIyAgcDIgPC0gRmVhdHVyZVNjYXR0ZXIoc29ial9saXN0W1tpXV0sIGZlYXR1cmUxID0gIm5GZWF0dXJlX1JOQSIsIGZlYXR1cmUyID0gInBlcmNlbnQubXQiLCBjb2xzID0gImJsYWNrIikgKyBnZ3RpdGxlKHBhc3RlKCJQZXJjZW50LU1UIHZzIG5HZW5lcyIsIHNvYmpfbGlzdFtbaV1dQG1ldGEuZGF0YVsxLDFdLCBzZXAgPSAiIC0gIikpICsgeWxhYigiUGVyY2VudCBNdGlvY2hvbmRyaWFsIEdlbmVzICglKSIpICsgeGxhYigiTnVtYmVyIG9mIEdlbmVzIikgKyBOb0xlZ2VuZCgpCiMgIHAzIDwtIEZlYXR1cmVTY2F0dGVyKHNvYmpfbGlzdFtbaV1dLCBmZWF0dXJlMSA9ICJuQ291bnRfUk5BIiwgZmVhdHVyZTIgPSAicGVyY2VudC5tdCIsIGNvbHMgPSAiYmxhY2siKSArIGdndGl0bGUocGFzdGUoIlBlcmNlbnQtTVQgdnMgblVNSXMiLCBzb2JqX2xpc3RbW2ldXUBtZXRhLmRhdGFbMSwxXSwgc2VwID0gIiAtICIpKSArIHlsYWIoIlBlcmNlbnQgTXRpb2Nob25kcmlhbCBHZW5lcyAoJSkiKSArIHhsYWIoIk51bWJlciBvZiBVTUlzIChSTkEgTW9sZWN1bGVzKSIpICsgTm9MZWdlbmQoKQojICBwcmludChwMSkgIyBvciBTQVZFCiMgIHByaW50KHAyKSAKIyAgcHJpbnQocDMpICAgCmBgYAoKCmBgYHtyIGNwbSBub3JtYWxpemF0aW9uLCBlY2hvPUZBTFNFLCByZXN1bHRzPSdoaWRlJywgaW5jbHVkZT1GQUxTRX0KIyMjIyMjIyMjIyMjIyMjIyMjIyMgQ2h1bmsgIyMjIyMjIyMjIyMjIyMjIyMjIyMgCiMgLy8gVGhpcyBjaHVuayB0YWtlcyBDUE0oMTAuMDAwKSBub3JtYWxpemVzIHRoZSByYXcgY291bnQgbWF0cml4IGFuZCBhcHBlbmRzIGl0IGluIGEgbmV3IGRhdGEgc2xvdAojIC8vIFRoZSByYXcgY291bnQgbWF0cml4IHdpbGwgbm90IGJlIHRyYW5zZm9ybWVkIGFuZCBuYXRpdmUgdmVyc2lvbiB3aWxsIGJlIHN0b3JlZCBpbiBpdHMgcHJldmlvdXMgc2xvdAojIyMjIyMjIyMjIyMjIyMjIyMjIyAgICAgICAjIyMjIyMjIyMjIyMjIyMjIyMjIyAKCiMjIyMjIyMjIyMgRnVuY3Rpb24gIyMjIyMjIyMjIyAKIyAvLyBUaGlzIGZ1bmN0aW9uIHJldHVybnMgYXBwbGllcyBhIENQTS1sb2coMTAuMDAwKSBub3JtYWxpemF0aW9uIG9uIHRoZSBjb3VudCBtYXRyaXggZm9yIGVhY2ggb2JqZWN0CiMgLy8gSW5wdXQgZmlsZSBtdXN0IGJlIGEgdmVjdG9yIG9mIFNldXJhdCBvYmplY3RzCkNQTV9ub3JtIDwtIGZ1bmN0aW9uKHNvYmopIHsKICBzb2JqIDwtIE5vcm1hbGl6ZURhdGEoc29iaiwgbm9ybWFsaXphdGlvbi5tZXRob2QgPSAiTG9nTm9ybWFsaXplIiwgc2NhbGUuZmFjdG9yID0gMTAwMDApCiAgcmV0dXJuKHNvYmopCn0KIyBFeGVjdXRlIENQTV9ub3JtIGZ1bmN0aW9uCnNvYmpfbGlzdCA8LSBzYXBwbHkoc29ial9saXN0LCBDUE1fbm9ybSkKYGBgCgojIyMjIFZpc3VhbGl6ZSB0aGUgaGlnaHkgdmFyaWFibGUgZ2VuZXM6ICMjIyMKCiMjIyMjIERlc2NyaXB0aW9uOiAjIyMjIwoKKiBXZSBmaXJzdCBlbXBsb3kgYSBsb2cgbm9ybWFsaXphdGlvbiBtZXRob2QgdGhhdCBub3JtYWxpemVzIHRoZSBnZW5lIGV4cHJlc3Npb24gY291bnRzIGZvciBlYWNoIGNlbGwgYnkgdGhlIHRvdGFsIGV4cHJlc3Npb24gYW5kIG11bHRpcGx5IHRoaXMgYnkgYSBzY2FsZSBmYWN0b3Igb2YgMTAsMDAwIGFuZCBsb2cgdHJhbnNmb3JtIGl0IHRvIHN0YWJpbGl6ZSB0aGUgdmFyaWFuY2Ugc28gdGhhdCBsYXJnZXIgdmFsdWVzIGRvIG5vdCBkb21pbmF0ZSBvdmVyIHNtYWxsZXIgb25lcy4KCiogVGhlbiB0aGUgdG9wIDIsNTAwIGdlbmVzICh1c2VyLWFkanVzdGFibGUpIHdpdGggbGFyZ2VzdCBzdGFuZGFyZGl6ZSB2YXJpYW5jZSB3aWxsIGJlIHNlbGVjdGVkIGF1dG9tYXRpY2FsbHkgYW5kIHVzZWQgZm9yIHRoZSBjbHVzdGVyaW5nLiBCeSBzZWxlY3RpbmcgaGlnaGx5IHZhcmlhYmxlIGdlbmVzLCB3ZSBlbnN1cmUgdGhhdCBob3VzZS1rZWVwaW5nIGdlbmVzIHdpdGggc2ltaWxhciBleHByZXNzaW9ucyBhY3Jvc3MgZGlmZmVyZW50IGNlbGxzIGRvIG5vdCBpbnRlcmZlcmUgd2l0aCB0aGUgdW5zdXBlcnZpc2VkIGNsdXN0ZXJpbmcuIAoKKiBOb3RlIHRoYXQgdGhlcmUgaXMgbm8gZGVmaW5pdGl2ZSBhbnN3ZXIgb24gaG93IG1hbnkgZ2VuZXMgb25lIHNob3VsZCBpbmNsdWRlIGZvciBjbHVzdGVyaW5nLiBUaHVzIGl0IGlzIHJlY29tbWVuZGVkIHRvIGNhcmVmdWxseSBjb25zaWRlciB0aGUgcmlnaHQgbnVtYmVyIG9yIGJ5IHRyeWluZyBhIHJhbmdlIG9mIDIwMDAtNTAwMCB2YXJpYWJsZSBnZW5lcy4gR2VuZXJhbGx5LCBsb3ctY29tcGxleGl0eSBkYXRhIChpLmUuIGRhdGEgd2l0aCBzaW1pbGFyIGNlbGxzKSB3aWxsIGhhdmUgbG93ZXIgbnVtYmVyIG9mIHZhcmlhYmxlIGdlbmVzIHdoZW4gY29tcGFyZWQgdG8gY29tcGxleCB0aXNzdWUuIEJ5IGRlZmF1bHQsIHdlIHdpbGwgc2VsZWN0IDI1MDAgaGlnaGx5IHZhcmlhYmxlIGdlbmVzLiAKCiMjIyMjIFJlc3VsdHM6ICMjIyMjCgoqIE1vc3QgVmFyaWFibGUgR2VuZXM6CiAgLSBUaGUgcGxvdCBzaG91bGQgbm90IGxvb2tzIGxpa2UgYSBmbGF0IGxpbmUuIFRoZXJlIHNob3VsZCBiZSBhIGNsZWFyIGRpc3RyaWJ1dGlvbiBvZiB0aGUgZ2VuZXMgd2l0aCB0aGUgbW9zdCBoaWdobHkgdmFyaWFibGUgb24gdGhlIHRvcC4gSWYgdGhlcmUgYXJlIG5vIGhpZ2hseSB2YXJpYWJsZSBnZW5lcyBpbiB5b3VyIGRhdGEsIHRoZW4geW91IGFyZSBsaWtlbHkgZGVhbGluZyB3aXRoIGNlbGxzIHRoYXQgaGF2ZSBzaW1pbGFyIGV4cHJlc3Npb24gbGV2ZWxzIG9mIHRoZSBzYW1lIGdlbmVzLiBUaGlzIGNhbiBkcmFzdGljYWxseSBpbXBhY3QgdGhlIGNsdXN0ZXJpbmcgYW5kIGFtYmllbnQgUk5BIGNvcnJlY3Rpb24gYXMgbW9zdCBkb3duc3RyZWFtIHN0ZXBzIGFyZSBjb21wdXRlZCBvbmx5IG9uIHRoZXNlIGdlbmVzLgpgYGB7ciBzaG93IG1vc3QgdmFyaWFibGUgZ2VuZXMsIGZpZy5oZWlnaHQ9NSwgZmlnLndpZHRoPTgsIGVjaG89RkFMU0UsIHdhcm5pbmc9RkFMU0UsIHJlc3VsdHM9J2hpZGUnfQojIyMjIyMjIyMjIyMjIyMjIyMjIyBDaHVuayAjIyMjIyMjIyMjIyMjIyMjIyMjIyAKIyAvLyBUaGlzIGNodW5rIHRha2VzIGFuZCB0aGUgY2FsY3VsYXRlZCB0aGUgdXNlciBzcGVjaWZpZWQgKG9yIGRlZmF1bHQgMjUwMCkgaGlnaGx5IHZhcmlhYmxlIGdlbmVzIHRvIGJlIHVzZWQgZm9yIGxhdGVyIGNsdXN0ZXJpbmcKIyAvLyBIaWdoIHZhcmlhYmlsaXR5IGlzIGZvdW5kIGJ5IGNhbGN1bGF0aW5nIHRoZSBzdGFuZGFyZGl6ZWQgdmFyaWFuY2UgYXMgZnVuY3Rpb24gb2YgbWVhbiBleHByZXNzaW9uCiMgLy8gT25seSB0aGVzZSBnZW5lcyB3aWxsIGJlIGNvbnNpZGVyZWQgZm9yIHVuc3VwZXJ2aXNlZCBjbHVzdGVyaW5nIG9mIHRoZSBjZWxscwojIyMjIyMjIyMjIyMjIyMjIyMjIyAgICAgICAjIyMjIyMjIyMjIyMjIyMjIyMjIyAKCiMjIyMjIyMjIyMgRnVuY3Rpb24gIyMjIyMjIyMjIyAKIyAvLyBUaGlzIGZ1bmN0aW9uIGNhbGN1bGF0ZXMsIHBsb3RzIGFuZCByZXR1cm5zIHRoZSB0b3AgMjAwMCBtb3N0IHZhcmlhYmxlIGdlbmVzIGJhc2VkIG9uIHRoZSBzdGFuZGFyZGl6ZWQgdmFyaWFuY2UKIyAvLyBJbnB1dCBmaWxlIG11c3QgYmUgYSB2ZWN0b3Igb2YgU2V1cmF0IG9iamVjdHMKbW9zdF92YXJfZ2VuZXMgPC0gZnVuY3Rpb24oc29iaikgewogIGlmIChuZmVhdHVyZXMgPj0gMCAmIG5mZWF0dXJlcyA8PSA1MDAwICYgbmZlYXR1cmVzID49IDIwMDAgJiBpcy5uYShuZmVhdHVyZXMpID09IEZBTFNFKXsKICAgIHNvYmogPC0gRmluZFZhcmlhYmxlRmVhdHVyZXMoc29iaiwgc2VsZWN0aW9uLm1ldGhvZCA9ICJ2c3QiLCBuZmVhdHVyZXMgPSBuZmVhdHVyZXMpICMjIyMgQU9UT01BVEUgVEhFIE5VTUJFUiBPRiBWQVJJQUJMRVMgKGJ1dCBiYXNlZCBvbiB3aGF0IGxvZ2ljPykKICB9IGVsc2UgewogICAgICBzb2JqIDwtIEZpbmRWYXJpYWJsZUZlYXR1cmVzKHNvYmosIHNlbGVjdGlvbi5tZXRob2QgPSAidnN0IiwgbmZlYXR1cmVzID0gMjUwMCkKICAgIH0KICAjIFNhdmUgdGhlIHRvcCAxMCBvZiB0aGUgMjAwMCBnZW5lcyAoZm9yIHZpc3VhbGl6YXRpb24pCiAgdG9wMTAuc29iaiA8LSBoZWFkKFZhcmlhYmxlRmVhdHVyZXMoc29iaiksIDEwKQogICMgUGxvdCB0aGUgbW9zdCB2YXJpYWJsZSBnZW5lcyBhbmQgdGhlIHRvcCAxMAogIHBsb3QxIDwtIFZhcmlhYmxlRmVhdHVyZVBsb3Qoc29iaikKICBwbG90MiA8LSBMYWJlbFBvaW50cyhwbG90ID0gcGxvdDEsIHBvaW50cyA9IHRvcDEwLnNvYmopCiAgcHJpbnQocGxvdDIgKyBnZ3RpdGxlKHBhc3RlKCJNb3N0IFZhcmlhYmxlIEdlbmVzIiwgc29iakBtZXRhLmRhdGFbMSwxXSwgc2VwID0gIiAtICIpKSkKICAKICByZXR1cm4oc29iaikKfQojIEV4ZWN1dGUgbW9zdF92YXJfZ2VuZXMgZnVuY3Rpb24Kc29ial9saXN0IDwtIHNhcHBseShzb2JqX2xpc3QsIG1vc3RfdmFyX2dlbmVzKQoKIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMgVEVTVElORyBDT0RFIEZPUiBTSU5HTEVUUyAjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMKI3NvYmogPC0gRmluZFZhcmlhYmxlRmVhdHVyZXMoc29iaiwgc2VsZWN0aW9uLm1ldGhvZCA9ICJ2c3QiLCBuZmVhdHVyZXMgPSAyNTAwKSAjIyMjIEFPVE9NQVRFIFRIRSBOVU1CRVIgT0YgVkFSSUFCTEVTCiMgU2F2ZSB0aGUgdG9wIDEwIG9mIHRoZSAyMDAwIGdlbmVzIChmb3IgdmlzdWFsaXphdGlvbikKI3RvcDEwLnNvYmogPC0gaGVhZChWYXJpYWJsZUZlYXR1cmVzKHNvYmopLCAxMCkKIyBQbG90IHRoZSBtb3N0IHZhcmlhYmxlIGdlbmVzIGFuZCB0aGUgdG9wIDEwCiNwbG90MSA8LSBWYXJpYWJsZUZlYXR1cmVQbG90KHNvYmopCiNwbG90MiA8LSBMYWJlbFBvaW50cyhwbG90ID0gcGxvdDEsIHBvaW50cyA9IHRvcDEwLnNvYmopCiNwbG90MiArIGdndGl0bGUoIk1vc3QgVmFyaWFibGUgR2VuZXMiKQpgYGAKCgpgYGB7ciBzY2FsaW5nIG9mIHRoZSBkYXRhLCBmaWcuaGVpZ2h0PTEwLCBmaWcud2lkdGg9NywgcmVzdWx0cz0naGlkZScsIGVjaG89RkFMU0UsIGluY2x1ZGU9RkFMU0V9CiMjIyMjIyMjIyMjIyMjIyMjIyMjIENodW5rICMjIyMjIyMjIyMjIyMjIyMjIyMjIAojIC8vIFRoaXMgY2h1bmsgdGFrZXMgdGhlIG5vcm1hbGl6ZWQgbWF0cml4IHNsb3QgYW5kIHNjYWxlcyB0aGUgZGF0YSBhbmQgYXBwZW5kcyBpdCBpbiBhIG5ldyBzY2FsZWQuZGF0YSBzbG90CiMgLy8gRWFjaCBmZWF0dXJlIHdpbGwgYmUgY2VudGVyZWQgdG8gaGF2ZSBhIG1lYW4gb2YgMCBhbmQgc2NhbGVkIGJ5IHRoZSBzdGFuZGFyZCBkZXZpYXRpb24gb2YgZWFjaCBmZWF0dXJlIAojIC8vIFRoaXMgc3RlcCBnaXZlcyBlcXVhbCB3ZWlnaHQgdG8gdGhlIGdlbmVzLCBzbyB0aGF0IGhpZ2hseS1leHByZXNzZWQgZ2VuZXMgZG8gbm90IGRvbWluYXRlIGZvciBkb3duc3RyZWFtIChlLmcuIFBDQSBhbmQgY2x1c3RlcmluZykKIyMjIyMjIyMjIyMjIyMjIyMjIyMgICAgICAgIyMjIyMjIyMjIyMjIyMjIyMjIyMgCgojIyMjIyMjIyMjIEZ1bmN0aW9uICMjIyMjIyMjIyMgCiMgLy8gVGhpcyBmdW5jdGlvbiBzaGlmdHMgdGhlIGV4cHJlc3Npb24gb2YgZWFjaCBnZW5lLCBzbyB0aGF0IHRoZSBtZWFuIGV4cHJlc3Npb24gYWNyb3NzIGNlbGxzIGlzIDAgCiMgLy8gVGhpcyBmdW5jdGlvbnMgc2NhbGVzIHRoZSBleHByZXNzaW9uIG9mIGVhY2ggZ2VuZSwgc28gdGhhdCB0aGUgdmFyaWFuY2UgYWNyb3NzIGNlbGxzIGlzIDEKIyAvLyBUaGUgZnVuY3Rpb24gcmV0dXJucyB0aGUgc2NhbGVkIHJlc3VsdHMgdG8gb2JqZWN0QHNjYWxlLmRhdGEgZm9yIGVhY2ggU2V1cmF0IG9iamVjdAojIC8vIElucHV0IGZpbGUgbXVzdCBiZSBhIHZlY3RvciBvZiBTZXVyYXQgb2JqZWN0cwpzY2FsaW5nIDwtIGZ1bmN0aW9uKHNvYmopIHsKICBhbGwuZ2VuZXMuc29iaiA8LSByb3duYW1lcyhzb2JqKQogIHNvYmogPC0gU2NhbGVEYXRhKHNvYmosIGZlYXR1cmVzID0gYWxsLmdlbmVzLnNvYmopIAogIHJldHVybihzb2JqKQp9CiMgRXhlY3V0ZSBzY2FsaW5nIGZ1bmN0aW9uCnNvYmpfbGlzdCA8LSBzYXBwbHkoc29ial9saXN0LCBzY2FsaW5nKQoKCiMgRXZlbiB0aG91Z2ggd2UgZ290IHJpZCBvZiBjZWxscyB0aGF0IGhhZCBhIGxvdCBvZiBNVCBSTkEsIHRoZXJlIG1pZ2h0IHN0aWxsIGJlIHNvbWUgY2VsbHMgcmVtYWluIHRoYXQgaGF2ZSBoaWdobHkgdmFyaWFibGUgTVQgUk5BCiMgU28gd2Ugd2lsbCByZWdyZXNzIG91dCBhbGwgdGhlIE1UIHJ1YmJpc2gKIyBzY2FsZSB1c2luZyBhbGwgZ2VuZXMgYW5kIHJlZ3Jlc3Mgb3V0IHJlbWFpbmluZyBoaWdobHkgdmFyaWFibGUgTVQgZ2VuZXMgaXMgdGhlcmUgaXMgYW55IGxlZnQ6CiNzb2JqIDwtIFNjYWxlRGF0YShzb2JqLCBmZWF0dXJlcyA9IGFsbC5nZW5lcy5zb2JqLCB2YXJzLnRvLnJlZ3Jlc3MgPSAncGVyY2VudC5tdCcpIAoKI3NjYWxlLnRvcC5zb2JqIDwtIFNjYWxlRGF0YShzb2JqKSAjLCB2YXJzLnRvLnJlZ3Jlc3MgPSAncGVyY2VudC5tdCcpICMgaGVyZSB3ZSBvbmx5IHNjYWxlIHRoZSAyMDAwIHByZXZpb3VzIGhpZ2hseSB2YXJpYWJsZSBnZW5lcwpgYGAKCiMjIyMgVW5zdXBlcnZpc2VkIGNsdXN0ZXJpbmc6IFBDQSAjIyMjCgojIyMjIyBEZXNjcmlwdGlvbjogIyMjIyMKCiogSGVyZSwgd2UgY2Fycnkgb3V0IGEgbGluZWFyIGRpbWVuc2lvbmFsIHJlZHVjdGlvbiB1c2luZyBQQ0Egb24gdGhlIHNjYWxlZCBkYXRhIGNvbnRhaW5pbmcgdGhlIG1vc3QgdmFyaWFibGUgZ2VuZXMgKGFzIGNob3NlbiBiZWZvcmUpOgogIC0gQmVmb3JlIHB1dHRpbmcgdGhlIGhpZ2hseSB2YXJpYWJsZSBnZW5lcyBpbnRvIFBDQSwgd2Ugd2lsbCBzcGVjaWZpY2FsbHkgc2NhbGUgdGhvc2UgZ2VuZXMgc28gdGhhdCB0aGV5IGhhdmUgYSBtZWFuIG9mIDAgYW5kIGEgdmFyaWFuY2Ugb2YgMS4gTW9yZSBzcGVjaWZpY2FsbHksIEZvciBlYWNoIGhpZ2hseSB2YXJpYWJsZSBnZW5lLCBhIHJlZ3Jlc3Npb24gbW9kZWwgaXMgYnVpbGQgdXNpbmcgdGhhdCBnZW5lJ3MgZXhwcmVzc2lvbiBsZXZlbCBhY3Jvc3MgYWxsIGNlbGxzLCBhbmQgdGhlbiBzaGlmdCB0aGUgcmVzaWR1YWwgdG8gemVybyBhbmQgZGl2aWRlZCBpdCBieSBzdGFuZGFyZCBkZXZpYXRpb24uCiAgLSBXZSBhcmUgZXNzZW50aWFsbHkgc2NhbGluZyBhbmQgY2VudGVyaW5nIHRoZXNlIGdlbmVzIGluIHRoZSBkYXRhc2V0LCB3aGljaCBzdGFuZGFyZGl6ZXMgdGhlIHJhbmdlIG9mIGV4cHJlc3Npb24gdmFsdWVzLiBUaGlzIHdpbGwgcmVncmVzc2VzIG91dCB1bndhbnRlZCBzb3VyY2VzIG9mIHZhcmlhdGlvbiBzdWNoIGFzIHRlY2huaWNhbCBub2lzZSBhbmQgZWFjaCBnZW5lIHdpbGwgY29udHJpYnV0ZXMgc2ltaWxhcmx5IHRvIHRoZSBkb3duc3RyZWFtIHN0ZXBzLiBBcyBhIHJlc3VsdCwgdGhlIFBDQSBhbmQgY2x1c3RlcmluZyB3aWxsIG5vdCBiZSBkb21pbmF0ZWQgYnkgdGhlIHNpZ25hbCBvZiBhIGZldyBoaWdobHktZXhwcmVzc2VkIGdlbmVzLgogIAoqIFRoZSByZWFzb24gdGhhdCB3ZSBkbyBhIFBDQSBpcyBiZWNhdXNlIHdlIHNpbXBseSBjYW5ub3Qgd29yayB3aXRoIHRoaXMgdWx0cmEgaGlnaCBkaW1lbnNpb25hbCBkYXRhIGZvciB0aGUgZG93bnN0cmVhbSBhbmFseXNpcy4gSW5zdGVhZCB3ZSBjYW4gbG9vayBhdCB3aGljaCBvZiB0aGUgbW9zdCB2YXJpYWJsZSBnZW5lcyBleHBsYWlucyBtb3N0IG9mIHRoZSB2YXJpYW5jZSBpbiB0aGUgZGF0YS4KICAKKiBOb3RlIHRoZSBQQ0EgaXMgYSBzdWl0YWJsZSBtZXRob2QsIGJ1dCBoYXMgc29tZSBkaXNhZHZhbnRhZ2VzOgogIC0gKEkgc3RpbGwgYmVsaWV2ZSB0aGF0IE1MIHdvdWxkIGJlIGEgYmV0dGVyIG9wdGlvbiBoZXJlLCBidXQgaXQgaXMgbm90IGJlbmNobWFya2VkIGluIHNpbmdsZS1jZWxsIGRhdGEgYXMgYW4gYWx0ZXJuYXRpdmUgdG8gUENBKS4KICAtIFBDQSBpcyB2ZXJ5IHBvcHVsYXIsIGJ1dCBmYWlscyB0byBjYXB0dXJlIGFsbCBzaWduYWxzIGNvbnNpZGVyaW5nIHRoYXQgMkQgZGltZW5zaW9uYWxpdHkgcmVkdWN0aW9uIGNhbm5vdCBjYXB0dXJlIGZhaW50IHNpZ25hbC4KCiMjIyMjIFJlc3VsdHM6ICMjIyMjCgoqIFBDQSBlbGJvdyBwbG90OiAgIFdlIHdpbGwgZmluZCB0aGUgb3B0aW1hbCBudW1iZXIgb2YgZGltZW5zaW9ucyBmb3IgZG93bnN0cmVhbSBhbmFseXNpcywgYmFzZWQgb246CiAgLSBQQyB3aGVyZSBjaGFuZ2UgaW4gcGVyY2VudCB2YXJpYXRpb24gaXMgbW9yZSB0aGFuIDElLgogIC0gT3IsIFBDcyByZXByZXNlbnRpbmcgY3VtdWxhdGl2ZSBwZXJjZW50ID45MCUgYW5kIGxlc3MgdGhhbiA1JSBhc3NvY2lhdGVkIHdpdGggdGhlIHNpbmdsZSBQQy4KICAtIFdpdGggZWFjaCBQQyByZXByZXNlbnRpbmcgY29tYmluZWQgaW5mb3JtYXRpb24gb2YgcG9zaXRpdmUgYW5kIG5lZ2F0aXZlIGNvcnJlbGF0ZWQgZ2VuZSBzZXRzLCB0aGUgdG9wIFBDcyByZXByZXNlbnQgc3Ryb25nIGNvbXByZXNzaW9uIG9mIHRoZSB0b3RhbCBkYXRhc2V0IHRoYXQgY2FuIGJlIHVzZWQgZm9yIGZ1cnRoZXIgZGltZW5zaW9uYWxpdHkgcmVkdWN0aW9uIGFuZCBjbHVzdGVyaW5nLiBJZiB5b3UgZmluZCBsZXNzIHRoYW4gMTAgUENzIGluIHRoZSBlbGJvdyBwbG90LCB5b3VyIGRhdGEgbGlrZWx5IGNvbnRhaW5zIHRvbyBmZXcgcmVsZXZhbnQgZ2VuZXMgZm9yIHN1Y2Nlc3NmdWwgY2x1c3RlcmluZy4gQWZ0ZXIgYWxsLCB3ZSBhcmUgbG9va2luZyBmb3IgZ2VuZXMgdGhhdCBjYW4gZXhwbGFpbiB0aGUgdmFyaWFuY2UgaW4geW91ciBjZWxscywgYW5kIGlmIG5vIHN1Y2ggZ2VuZXMgY2FuIGJlIGZvdW5kIChvciB0b28gZmV3IG9mIHRoZW0pIHRoZW4gdGhlIGRvd25zdHJlYW0gc3RlcHMgd2lsbCBoYXZlIGRpZmZpY3VsdGllcyB0byBmaW5kIHRoZSBkaWZmZXJlbmNlcyBiZXR3ZWVuIHlvdXIgY2VsbHMuIEhvd2V2ZXIsIGlmIHlvdSBhcmUgd29ya2luZyB3aXRoIGxvdy1jb21wbGV4aXR5IGRhdGEgKGUuZy4gc2ltaWxhciBjZWxsIHR5cGVzIGluIGRpZmZlcmVudCBiaW9sb2dpY2FsIHN0YXRlcykgdGhlbiB5b3Ugc2hvdWxkIHRvIGZpbmQgZmV3ZXIgbnVtYmVyIG9mIFBDcy4KICAtIFRoZSBkYXNoZWQgcmVkIGxpbmUgaW4gdGhlIHBsb3Qgc2hvd3MgdGhlIG9wdGltYWwgbnVtYmVyIFBDIGRpbWVuc2lvbnMuCmBgYHtyIHNjYWxpbmcgYW5kIFBDQSwgZmlnLmhlaWdodD00LCBmaWcud2lkdGg9OCwgZWNobz1GQUxTRSwgcmVzdWx0cz0naGlkZScsIGluY2x1ZGU9RkFMU0V9CiMjIyMjIyMjIyMjIyMjIyMjIyMjIENodW5rICMjIyMjIyMjIyMjIyMjIyMjIyMjIAojIC8vIFRoaXMgY2h1bmsgdGFrZXMgdGhlIHNjYWxlZCBub3JtYWxpemVkIG1hdHJpeCBhbmQgcGVyZm9ybXMgUENBIG9uIG4gdXNlciBkZWZpbmVkIGhpZ2hseSB2YXJpYWJsZSBmZWF0dXJlcwojIC8vIFRoZSBzdG9yZWQgUENBIGluZm9ybWF0aW9uIHdpbGwgbGV2ZXJhZ2VkIGJ5IGEgc2Vjb25kIGZ1bmN0aW9uIHRvIGNhbGN1bGF0ZSB0aGUgb3B0aW1hbCBQQ3MgZm9yIGNsdXN0ZXJpbmcKIyMjIyMjIyMjIyMjIyMjIyMjIyMgICAgICAgIyMjIyMjIyMjIyMjIyMjIyMjIyMgCgojIyMjIyMjIyMjIEZ1bmN0aW9uICMjIyMjIyMjIyMgCiMgLy8gVGhpcyBmdW5jdGlvbiBydW5zIGEgUENBIG9uIHRoZSBuIHVzZXIgZGVmaW5lZCAob3IgZGVmYXVsdCkgbW9zdCB2YXJpYWJsZSBlYWNoIG9iamVjdCAKIyAvLyBCeSBkZWZhdWx0IHVwIHRvIDEwMCBQQ3MgYXJlIGNhbGN1bGF0ZWQKIyAvLyBJbnB1dCBmaWxlIG11c3QgYmUgYSB2ZWN0b3Igb2YgU2V1cmF0IG9iamVjdHMKcnVuX1BDQSA8LSBmdW5jdGlvbihzb2JqKSB7CiAgc29iaiA8LSBSdW5QQ0Eoc29iaiwgZmVhdHVyZXMgPSBWYXJpYWJsZUZlYXR1cmVzKG9iamVjdCA9IHNvYmopKQogIHJldHVybihzb2JqKQp9CiMgRXhlY3V0ZSBydW5fUENBIGZ1bmN0aW9uCnNvYmpfbGlzdCA8LSBzYXBwbHkoc29ial9saXN0LCBydW5fUENBKQoKIyMjIyMjIyMjIyBGdW5jdGlvbiAjIyMjIyMjIyMjIAojIC8vIFRoaXMgZnVuY3Rpb24gY2FsY3VsYXRlcyByZXR1cm5zIHRoZSBvcHRpbWFsIG51bWJlciBvZiBQQ3MgZm9yIGNsdXN0ZXJpbmcuCiMgLy8gTWV0aG9kMTogbGFzdCBQQyB3aGVyZSBjaGFuZ2UgaW4gcGVyY2VudCB2YXJpYXRpb24gaXMgbW9yZSB0aGFuIDAuNSUKIyAvLyBNZXRob2QyOiBQQ3MgcmVwcmVzZW50aW5nIGN1bXVsYXRpdmUgcGVyY2VudCA+OTAlIGFuZCBsZXNzIHRoYW4gNSUgYXNzb2NpYXRlZCB3aXRoIHRoZSBzaW5nbGUgUEMKIyAvLyBJbnB1dCBmaWxlIG11c3QgYmUgYSB2ZWN0b3Igb2YgU2V1cmF0IG9iamVjdHMKb3B0aW1hbF9QQ3MgPC0gZnVuY3Rpb24oc29iaikgewogIHBjLnN0ZGV2LnBlcmNlbnRhZ2UgPC0gc29ialtbInBjYSJdXUBzdGRldiAvIHN1bShzb2JqW1sicGNhIl1dQHN0ZGV2KSAqIDEwMCAjIGZpbmQgc3RhbmRhcmQgZGV2aWF0aW9uIGZvciBlYWNoIFBDCiAgY3VtdS5wZXJjZW50YWdlIDwtIGN1bXN1bShwYy5zdGRldi5wZXJjZW50YWdlKSAjIGZpbmQgY3VtdWxhdGl2ZSBwZXJjZW50YWdlcyBmb3IgUENzCiAgY28xIDwtIHdoaWNoKGN1bXUucGVyY2VudGFnZSA+IDkwICYgcGMuc3RkZXYucGVyY2VudGFnZSA8IDUpWzFdICMgZmluZCBQQ3MgcmVwcmVzZW50aW5nIGN1bXVsYXRpdmUgcGVyY2VudCA+OTAlIGFuZCBsZXNzIHRoYW4gNSUgYXNzb2NpYXRlZCB3aXRoIHRoZSBzaW5nbGUgUEMKICBjbzEgIyBsaXN0IFBDCiAgY28yIDwtIHNvcnQod2hpY2goKHBjLnN0ZGV2LnBlcmNlbnRhZ2VbMTpsZW5ndGgocGMuc3RkZXYucGVyY2VudGFnZSkgLSAxXSAtIHBjLnN0ZGV2LnBlcmNlbnRhZ2VbMjpsZW5ndGgocGMuc3RkZXYucGVyY2VudGFnZSldKSA+IDAuMDEpLCAKICAgICAgICAgICAgICBkZWNyZWFzaW5nID0gVClbMV0gIysgMSAjIGZpbmQgbGFzdCBQQyB3aGVyZSBjaGFuZ2UgaW4gcGVyY2VudCB2YXJpYXRpb24gaXMgbW9yZSB0aGFuIDElIGFuZCBhZGQgYW5kIGV4dHJhIFBDIHRvIGl0CiAgY28yICMgbGlzdCBQQwogIHBjcyA8LSBtaW4oY28xLCBjbzIpICMgZmluZCB0aGUgbWluaW11bSBQQyBmcm9tIHRoZSAyIG1ldGhvZHMgdXNlZCBhYm92ZQogIHBjcyA8IG1heChwY3MpICMgbGlzdCBQCiAgcGMuZGltcyA8LSAxOnBjcyAjIHdlIHdpbGwgdXNlIHRoZXNlIGRpbWVuc2lvbiBsYXRlciBvbgogIAogIHBsb3RfZGYgPC0gZGF0YS5mcmFtZShwYy5zdGRldi5wZXJjZW50YWdlID0gcGMuc3RkZXYucGVyY2VudGFnZSwgIyBwdXQgUEMgdmFsdWVzIGludG8gZGF0YWZyYW1lIGZvciBwbG90dGluZwogICAgICAgICAgICAgICAgICAgICAgY3VtdSA9IGN1bXUucGVyY2VudGFnZSwgCiAgICAgICAgICAgICAgICAgICAgICByYW5rID0gMTpsZW5ndGgocGMuc3RkZXYucGVyY2VudGFnZSkpCiAgCiAgb3B0X1BDX3Bsb3QgPC0gZ2dwbG90KHBsb3RfZGYsIGFlcyhjdW11LnBlcmNlbnRhZ2UsIHBjLnN0ZGV2LnBlcmNlbnRhZ2UsIGxhYmVsID0gcmFuaywgY29sb3IgPSByYW5rID4gcGNzKSkgKyAKICAgIGdlb21fdGV4dCgpICsgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gOTAsIGNvbG9yID0gImdyZXkiKSArIAogICAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gbWluKHBjLnN0ZGV2LnBlcmNlbnRhZ2VbcGMuc3RkZXYucGVyY2VudGFnZSA+IDVdKSwgY29sb3IgPSAiZ3JleSIpICsgdGhlbWVfYncoKSAjIHZpc3VhbGl6ZSBQQ3MgdG8gdXNlIGluIGVsYm93IHBsb3QKICBwcmludChvcHRfUENfcGxvdCkKICAKICByZXR1cm4obGlzdChwYy5kaW1zKSkKfQojIEV4ZWN1dGUgb3B0aW1hbF9QQyBmdW5jdGlvbgpwYy5kaW1zIDwtIHNhcHBseShzb2JqX2xpc3QsIG9wdGltYWxfUENzKQoKCiNwcmludChpbGV1bS5vcmcuaW5jbC5pbnRyLnNldVtbJ3BjYSddXSwgZGltcyA9IDE6NSwgbmZlYXR1cmVzID0gNSkKI1ZpekRpbUxvYWRpbmdzKGlsZXVtLm9yZy5pbmNsLmludHIuc2V1LCBkaW1zID0gMToyLCByZWR1Y3Rpb24gPSAncGNhJykKIyBEaW1QbG90KGlsZXVtLm9yZy5pbmNsLmludHIuc2V1LCByZWR1Y3Rpb24gPSAncGNhJykKYGBgCgpgYGB7ciBQQ0EgZWxib3cgcGxvdCB0byBmaW5zIG1vc3Qgc2lnbmlmaWNhbnQgUENzLCBmaWcuaGVpZ2h0PTUsIGZpZy53aWR0aD02LCBlY2hvPUZBTFNFfQojIyMjIyMjIyMjIyMjIyMjIyMjIyBDaHVuayAjIyMjIyMjIyMjIyMjIyMjIyMjIyAKIyAvLyBUaGlzIGNodW5rIHRha2VzIHBsb3RzIGFuIEVsYm93IHdpdGggb3B0aW1hbCBQQ3MgYmVpbmcgZGlzcGxheWVkCiMjIyMjIyMjIyMjIyMjIyMjIyMjICAgICAgICMjIyMjIyMjIyMjIyMjIyMjIyMjIAoKIyBQbG90IGFuZCBFbGJvdyB0byB2aXN1YWxpemUgdGhlIG9wdGltYWwgUEMgYmFzZWQKZm9yIChpIGluIDE6bGVuZ3RoKHggPSBwYy5kaW1zKSkgewogIGUxIDwtIEVsYm93UGxvdChzb2JqX2xpc3RbW2ldXSwgbmRpbXMgPSA0MCkgKyAKICAgIGdndGl0bGUocGFzdGUoIlNpZ25pZmljYW50IFBDcyIsIHNvYmpfbGlzdFtbaV1dQG1ldGEuZGF0YVsxLDFdLCBzZXAgPSAiIC0gIikpICsgCiAgICBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSBtYXgodW5saXN0KHBjLmRpbXNbW2ldXSkpLCBsaW5ldHlwZT0iZGFzaGVkIiwgY29sb3IgPSAicmVkIiwgc2l6ZT0xKSArIAogICAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIpKQogIHByaW50KGUxKSAjIyMjIyMjIFNBVkUgRk9SIFBJUEVMSU5FCn0KYGBgCgpgYGB7ciBQQ0Egc2VsZWN0aW9uLCBmaWcuaGVpZ2h0PTE3LCBmaWcud2lkdGg9OSwgZWNobz1GQUxTRSwgcmVzdWx0cz0naGlkZScsIGluY2x1ZGU9RkFMU0V9CiMgLy8gVGhpcyBmdW5jdGlvbiByZXR1cm5zIGhlYXRtYXBzIG9mIHRoZSB0b3AgMzAgUENzIG1ldGEgZ2VuZXMgb2YgNTAwIGNlbGxzIHBlciBQQwojIC8vIElucHV0IGZpbGUgbXVzdCBiZSBhIHZlY3RvciBvZiBTZXVyYXQgb2JqZWN0cwpydW5fUENBX2hlYXRtYW4gPC0gZnVuY3Rpb24oc29iaikgewogIFBDQV9oZWF0bWFwIDwtIERpbUhlYXRtYXAoc29iaiwgZGltcyA9IDE6MzAsIGNlbGxzID0gNTAwLCBiYWxhbmNlZCA9IFRSVUUpICMgZmFzdCA9IEZBTFNFIHVzZXMgZ2dwbG90IAogIHByaW50KFBDQV9oZWF0bWFwKQogIHJldHVybigpCn0KCiMgRXhlY3V0ZSBydW5fUENBX2hlYXRtYW4gZnVuY3Rpb24KUENBX2hlYXRtYXBzIDwtIHNhcHBseShzb2JqX2xpc3QsIHJ1bl9QQ0FfaGVhdG1hbikKYGBgCgojIyMjIEZpbmFsIGNsdXN0ZXJpbmcgKEtOTiAoU05OKSkgdXNpbmcgdGhlIG1vc3QgZXhwbGFpbmVkIFBDcyBhbmQgcHJvamVjdGlvbiBvbnRvIFVNQVA6ICMjIyMKCiMjIyMjIERlc2NyaXB0aW9uOiAjIyMjIwoKKiBPcmlnaW5hbCBMb3V2YWluIGFsZ29yaXRobToKICAtIEJhc2VkIG9uIHRoZSBFdWNsaWRlYW4gZGlzdGFuY2UgaW4gdGhlIFBDQSBzcGFjZSwgdGhlIHBpcGVsaW5lIGNhcnJpZXMgb3V0IGEgSy1uZWFyZXN0IG5laWdoYm9yIGdyYXBoIChrPTIwIGJ5IGRlZmF1bHQpIGFuZCByZWZpbmVzIHRoZSBlZGdlIGJldHdlZW4gYW55IHR3byBjZWxscyBiYXNlZCBvbiBzaGFyZWQgb3ZlcmxhcCBiZXR3ZWVuIHRoZWlyIGV4cHJlc3Npb24gcGF0dGVybnMgdXNpbmcgdGhlIHRyYWRpdGlvbmFsIEphY2NhcmQgc2ltaWxhcml0eSB0ZWNobmlxdWUuIAogIC0gVGhlIGNsdXN0ZXJzIGFyZSB0aGVuIGNvbnN0cnVjdGVkIGJ5IGpvaW5pbmcgdGhlIGdyb3VwcyBpbnRlcmFjdGl2ZWx5IHVudGlsIGl0IGZ1bGx5IGNvbnZlcmdlcyB1c2luZyB0aGUgTG91dmFpbiBhbGdvcml0aG0uIENlbGxzIGFyZSB0aGVuIG1vdmVkIHRvIGEgbm9uLWxpbmVhciBVTUFQIHNwYWNlIGZvciB2aXN1YWxpemF0aW9uLiBIZXJlLCB3ZSBmaW5kIHRoYXQgYnkgdXNpbmcgYSByZXNvbHV0aW9uIG9mIDAuOCwgTG91dmFpbiBkb2VzIGEgZGVjZW50IGpvYiBpbiBpZGVudGlmeWluZyBzdWZmaWNpZW50IG51bWJlciBvZiBjb21tdW5pdGllcyBmb3IgYm90aCBoaWdoIGNvbXBsZXhpdHkgKHBvcmNpbmUgaWxldW0sIHdpdGggaW1tdW5lKSBhbmQgbG93LWNvbXBsZXhpdHkgZGF0YSAocG9yY2luZSBpbGV1bSBvcmdhbm9pZCBvciB0aXNzdWUsIG5vIGltbXVuZSkuCiAgLSBUbyByZXNvbHV0aW9uIG9mIDAuOCBpcyBzZXQgYXMgZGVmYXVsdCwgYnV0IG1vcmUgcmVzZWFyY2ggaXMgcmVxdWlyZWQgdG8gdXNlIGFuIGFkYXB0aXZlIHJlc29sdXRpb24gZGVwZW5kaW5nIG9uIHRoZSB0eXBlIG9mIGRhdGEgYXMgdGhpcyBwYXJhbWV0ZXIgY291bGQgZ3JlYXRseSBpbXBhY3QgdGhlIG51bWJlciBwcmVsaW1pbmFyeSBjbHVzdGVycyB0aGF0IHdpbGwgYmUgdXNlZCBieSB0aGUgYW1iaWVudCBSTkEgY29ycmVjdGluZyBhbGdvcml0aG0uIEFzIGFuIGV4cGVyaW1lbnRhbCBmZWF0dXJlLCB5b3UgYXJlIGFsbG93ZWQgdG8gY2hhbmdlIHRoZSByZXNvbHV0aW9uLCB3aGljaCB3aWxsIGltcGFjdCB0aGUgZmluYWwgbnVtYmVyIG9mIGNlbGwgY2x1c3RlcnMgKG5vdCByZWNvbW1lbmRlZCkuCiAgLSBJbiBjYXNlIHlvdSBlbmQgdXAgd2l0aCB0b28gZmV3IGNsdXN0ZXIgYnkgdGhlIGRlZmF1bHQgc2V0dGluZ3MsIHRoZW4gaXQgd29ydGggdG8gdHJ5IGEgcmVzb2x1dGlvbiA+MC44LiBJZiB5b3UgaGF2ZSB0b28gZmV3IGNsdXN0ZXJzLCB0aGUgYW1iaWVudCBSTkEgY29ycmVjdGlvbiBtaWdodCBiZWNvbWUgYmlhc2VkIChtb3JlIG9uIHRoaXMgbGF0ZXIuLi4pLgoKIyMjIyMgUmVzdWx0czogIyMjIyMKCiogVU1BUCBwbG90czogICBOdW1iZXIgb2YgZ2VuZXMvVU1Jcy9NVHMgYXJlIHNob3duIHBlciBjZWxsIHdpdGhpbiBlYWNoIGNsdXN0ZXI6CiAgLSBUaGVzZSBwbG90cyBjYW4gZ2l2ZSB1cyBhbiBpZGVhIHdoaWNoIGNlbGxzICh3aXRoaW4gY2x1c3RlcnMpIGNvbnRhaW4gbG93LCBtZWRpdW0gb3IgaGlnaCBudW1iZXIgb2YgZ2VuZXMgYW5kIHRvdGFsIFVNSXMuIAogIC0gTm90ZSB0aGF0IGhpZ2ggbnVtYmVyIG9mIGdlbmVzIG9yIFVNSXMgaXMgbm90IG5lY2Vzc2FyaWx5IGEgYmFkIHRoaW5nLCBidXQgaXMgc3RpbGwgaGlnaGxpZ2h0ZWQgd2l0aCAicHVycGxlIgogIC0gSW4gY2FzZSBvZiBhIGZhaWxlZCBleHBlcmltZW50IChsb3cgbnVtYmVyIG9mIGdlbmVzKSBkdWUgdG8gc2lnbmlmaWNhbnQgcG9wdWxhdGlvbiBvZiBjZWxscyB3aXRoIGEgbG93IFJOQSBjb250ZW50LCB0aGVzZSBwbG90cyBjYW4gc2hvdyB3aGljaCBncm91cHMgb2YgY2VsbHMgYXJlIGFmZmVjdGVkLiBBbmQgaWYgdGhlIHNhbWUgY2x1c3RlcnMgY29udGFpbiBoaWdoIHBlcmNlbnRhZ2UgTVQgZ2VuZXMsIHRoZW4gaXQgaXMgbGlrZWx5IHRoYXQgdGhvc2UgY2VsbHMgYXJlIGxvdy1xdWFsaXR5IG9yIGRlYWQuCiAgLSBIb3cgbWFueSBjbHVzdGVyIGRvIHlvdSBvYnNlcnZlIGluIHRvdGFsPyBEbyB5b3UgZXhwZWN0IHRvIHNlZSBtb3JlIChvciBsZXNzKSBiYXNlZCBvbiB3aGF0IHlvdSBhbHJlYWR5IGtub3cgYWJvdXQgeW91ciBzYW1wbGVzPwpgYGB7ciBtYWtlIHVtYXAsIGZpZy5oZWlnaHQ9NSwgZmlnLndpZHRoPTYsIGVjaG89RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIHJlc3VsdHM9J2hpZGUnfQojIyMjIyMjIyMjIyMjIyMjIyMjIyBDaHVuayAjIyMjIyMjIyMjIyMjIyMjIyMjIyAKIyAvLyBUaGlzIGNodW5rIHBlcmZvcm1zIHRoZSB1bnN1cGVydmlzZWQgTG91dmFpbiBncmFwaCBiYXNlZCBjbHVzdGVyaW5nIHVzaW5nIHRoZSBvcHRpbWFsIFBDQSBtZXRhZmVhdHVyZXMgZnJvbSB0aGUgbiB1c2VyIGRlZmluZWQgaGlnaGx5IHZhcmlhYmxlIGdlbmVzCiMgLy8gVXNpbmcgdGhlIHZhbHVlcyBvZiB0aGUgbW9zdCByZWxldmFudCBQQ3MgdGhlIGNlbGxzIGFyZSBmb3J3YXJkZWQgaW50byBhIFVNQVAgcHJvamVjdGlvbgojIyMjIyMjIyMjIyMjIyMjIyMjIyAgICAgICAjIyMjIyMjIyMjIyMjIyMjIyMjIyAKCiMgY2x1c3RlcmluZyBieSBjYWxjdWxhdGluZyBrLW5lYXJlc3QgbmVpZ2hib3JzIGFuZCBjb25zdHJ1Y3QgdGhlIFNOTiBncmFwaCBieSB0aGUgb3JpZ2luYWwgTG91dmFpbiBhbGdvcml0aG0gdXNpbmcgdGhlIG9wdGltYWwgUENBIGRpbWVuc2lvbnMKZm9yIChpIGluIDE6bGVuZ3RoKHggPSBzYW1wbGVfbmFtZXMpKSB7CiAgc29ial9saXN0W1tpXV0gPC0gRmluZE5laWdoYm9ycyhzb2JqX2xpc3RbW2ldXSwgay5wYXJhbSA9IDIwLCBkaW1zID0gdW5saXN0KHBjLmRpbXNbW2ldXSkpICMgRmluZCBuZWlnaGJvcnMgb24gYnkgdXNpbmcgS05OIChrPTIwKSBhbmQgU05OIG5laWdoYm9yaG9vZCBvdmVybGFwIHVzaW5nIGphY2NhcmQgaW5kZXguCiAgc29ial9saXN0W1tpXV0gPC0gRmluZENsdXN0ZXJzKHNvYmpfbGlzdFtbaV1dLCByZXNvbHV0aW9uID0gdW1hcC5yZXNvbHV0aW9uKSAjIFdlIGRvIG5ldCB5ZXQgc2VsZWN0IGRpZmZlcmVudCByZXNvbHV0aW9ucyBhcyB0aGlzIGlzIHVubmVjZXNzYXJ5IGZvciBub3cuLi4gCiAgIyBMb29rIGF0IGNsdXN0ZXIgSURzIG9mIHRoZSBmaXJzdCA1IGNlbGxzCiAgIyBoZWFkKElkZW50cyhpbGV1bS5vcmcuaW5jbC5pbnRyLnNldSksIDUpLiAjIHRlc3QgY29kZQogICMgQ2FsY3VsYXRlIGFuZCBtYWtlIHRoZSBVTUFOIGFuZCBULVNORSBjbHVzdGVycwogIHNvYmpfbGlzdFtbaV1dIDwtIFJ1blVNQVAoc29ial9saXN0W1tpXV0sIGRpbXMgPSB1bmxpc3QocGMuZGltc1tbaV1dKSkKIyAgc29ial9saXN0W1tpXV0gPC0gUnVuVFNORShzb2JqX2xpc3RbW2ldXSwgZGltcyA9IHVubGlzdChwYy5kaW1zW1sxXV0pKQogIGQxIDwtIERpbVBsb3Qoc29ial9saXN0W1tpXV0sIHJlZHVjdGlvbiA9ICd1bWFwJywgbGFiZWwgPSBGQUxTRSwgcHQuc2l6ZSA9IDAuMDUpICsgCiAgICBnZ3RpdGxlKHBhc3RlKCJTTk46IFVNQVAiLCBzb2JqX2xpc3RbW2ldXUBtZXRhLmRhdGFbMSwxXSwgc2VwID0gIiAtICIpLCBzdWJ0aXRsZSA9IHBhc3RlKCJOdW1iZXIgb2YgQ2VsbHMgKG4gPSAiLCBwYXN0ZShkaW0oc29ial9saXN0W1tpXV0pWzJdLCAiKSIsIHNlcCA9ICIiKSkpICsgCiAgICB5bGFiKCJVTUFQIDEiKSArIHhsYWIoIlVNQVAgMiIpICsgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIpKQogIGQyIDwtIEZlYXR1cmVQbG90KHNvYmpfbGlzdFtbaV1dLCBmZWF0dXJlcz0ibkZlYXR1cmVfUk5BIiwgbGFiZWw9VFJVRSwgcHQuc2l6ZSA9IDAuMDUpICsgCiAgICBnZ3RpdGxlKHBhc3RlKHNvYmpfbGlzdFtbaV1dQG1ldGEuZGF0YVsxLDFdLCBzZXAgPSAiIC0gIiksIHN1YnRpdGxlID0gIkdlbmUgQ291bnQgcGVyIENsdXN0ZXIvQ2VsbCIpICsgCiAgICB5bGFiKCJVTUFQIDEiKSArIHhsYWIoIlVNQVAgMiIpICsgbGFicyhmaWxsID0gIm5HZW5lcyIsIGNvbG91ciA9ICJuR2VuZXMiLCBsYWJlbHMgPSAibkdlbmVzIiApICsgc2NhbGVfY29sb3VyX2dyYWRpZW50bihjb2xvdXJzID0gYygncmVkJywgImdyZWVuIiwgJ3B1cnBsZScpLCB2YWx1ZXMgPSBjKDAsICgyMDAgLyBtYXgoc29ial9saXN0W1sxXV1bWyJuRmVhdHVyZV9STkEiXV0kbkZlYXR1cmVfUk5BKSksIDEpKSArIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyKSkKIyAgZDIgPC0gRGltUGxvdChzb2JqX2xpc3RbW2ldXSwgcmVkdWN0aW9uID0gJ3RzbmUnLCBsYWJlbCA9IFRSVUUpICsgZ2d0aXRsZShwYXN0ZSgiU05OOiB0LVNORSIsIHNvYmpfbGlzdFtbaV1dQG1ldGEuZGF0YVsxLDFdLCBzZXAgPSAiIC0gIikpICsgeGxhYigidC1TTkUgMiIpCiAgZDMgPC0gRmVhdHVyZVBsb3Qoc29ial9saXN0W1tpXV0sIGZlYXR1cmVzPSJuQ291bnRfUk5BIiwgbGFiZWw9VFJVRSwgcHQuc2l6ZSA9IDAuMDUpICsgCiAgICBnZ3RpdGxlKHBhc3RlKHNvYmpfbGlzdFtbaV1dQG1ldGEuZGF0YVsxLDFdLCBzZXAgPSAiIC0gIiksIHN1YnRpdGxlID0gIlVNSSBDb3VudCBwZXIgQ2x1c3Rlci9DZWxsIikgKyAKICAgIHlsYWIoIlVNQVAgMSIpICsgeGxhYigiVU1BUCAyIikgKyBsYWJzKGZpbGwgPSAiblVNSXMiLCBjb2xvdXIgPSAiblVNSXMiLCBsYWJlbHMgPSAiblVNSXMiICkgKyBzY2FsZV9jb2xvdXJfZ3JhZGllbnRuKGNvbG91cnMgPSBjKCdyZWQnLCAiZ3JlZW4iLCAncHVycGxlJyksIHZhbHVlcyA9IGMoMCwgKDUwMCAvIG1heChzb2JqX2xpc3RbWzFdXVtbIm5Db3VudF9STkEiXV0kbkNvdW50X1JOQSkpLCAxKSkgKyB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMikpCiAgZDQgPC0gRmVhdHVyZVBsb3Qoc29ial9saXN0W1tpXV0sIGZlYXR1cmVzPSJwZXJjZW50Lm10IiwgbGFiZWw9VFJVRSwgcHQuc2l6ZSA9IDAuMDUpICsgCiAgICBnZ3RpdGxlKHBhc3RlKHNvYmpfbGlzdFtbaV1dQG1ldGEuZGF0YVsxLDFdLCBzZXAgPSAiIC0gIiksIHN1YnRpdGxlID0gIk1UIFBlcmNlbnRhZ2UgcGVyIENsdXN0ZXIvQ2VsbCIpICsgCiAgICB5bGFiKCJVTUFQIDEiKSArIHhsYWIoIlVNQVAgMiIpICsgbGFicyhmaWxsID0gIk1UICUiLCBjb2xvdXIgPSAiTVQgJSIsIGxhYmVscyA9ICJNVCAlIiApICsgCiAgICBzY2FsZV9jb2xvdXJfZ3JhZGllbnRuKGNvbG91cnMgPSBjKCdncmVlbicsICdyZWQnLCAncmVkNCcpLCB2YWx1ZXMgPSBjKDAsICgoKG1heChzb2JqX2xpc3RbW2ldXVtbInBlcmNlbnQubXQiXV0kcGVyY2VudC5tdCkgKiA0KSAvIDEwMCkgLyAxMCksIDEpKSArIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyKSkKICAjIFByaW50IHRoZSBwbG90cwogIHByaW50KGQxKQogIHByaW50KGQyKQogIHByaW50KGQzKQogIHByaW50KGQ0KQp9CgoKIyBTY2FsZWQgY29sb3IgZ3JhZGllbnQgdmFsdWVzIGZvciAic2NhbGVfY29sb3VyX2dyYWRpZW50biIgbWlkIHZhbHVlcwojKCgobWF4KHNvYmpfbGlzdFtbMV1dW1sicGVyY2VudC5tdCJdXSRwZXJjZW50Lm10KSAqIDEwMCkgLyAxMDApIC8gMTApICMgcGVyY2VudC5tdAojKDIwMCAvIG1heChzb2JqX2xpc3RbWzFdXVtbIm5GZWF0dXJlX1JOQSJdXSRuRmVhdHVyZV9STkEpKSAjIG5GZWF0dXJlX1JOQQojKDUwMCAvIG1heChzb2JqX2xpc3RbWzFdXVtbIm5Db3VudF9STkEiXV0kbkNvdW50X1JOQSkpICMgbkNvdW50X1JOQQoKIyJuRmVhdHVyZV9STkEiLCAibkNvdW50X1JOQSIsICJwZXJjZW50Lm10IgpgYGAKCiMjIyMgU291cFggQW1iaWVudCBSTkEgUmVtb3ZhbDogIyMjIwoKIyMjIyMgRGVzY3JpcHRpb246ICMjIyMjCgoqIFRlcm1pbm9sb2d5OgogIC0gVG90YWwgY29udGFtaW5hdGlvbiBpcyB0aGUgZnJhY3Rpb24gb2YgYW1iaWVudCBSTkEgKGZvciBlYWNoIGdlbmUpIGVzdGltYXRlZCBmcm9tIChzZW1pKS1lbXB0eSBkcm9wbGV0cyBmcm9tIHRoZSByYXcgY291bnRzIG1hdHJpeC4KICAtIENvbnRhbWluYXRpb24gZnJhY3Rpb25zIGlzIHRoZSB0aGUgZXN0aW1hdGVkIHRoZSBudW1iZXIgdHJhbnNjcmlwdHMgdGhhdCBhcmUgY29udHJpYnV0aW5nIHRvIHRoZSBwcmV2aW91c2x5IGNhbGN1bGF0ZWQgYmFja2dyb3VuZCBjb250YW1pbmF0aW9uIChmcm9tIGVtcHR5IGRyb3BsZXRzKSB1c2luZyB0aGUgZXhwcmVzc2lvbiBvZiBzZXZlcmFsIG1hcmtlciBnZW5lcyBiZXR3ZWVuIGNlbGwtY2x1c3RlcnMgd2hlcmUgaXQgZG9lcyBub3QgYmVsb25nLiBIZXJlIGl0IGlzIGFzc3VtZWQgdGhhdCB0aGUgYWJ1bmRhbmNlIG9mIGdlbmVzIHRoYXQgbWFrZSB1cCB0aGUgYmFja2dyb3VuZCBhcmUgbm90IGRpZmZlcmVudCBiZXR3ZWVuIHRoZSBjZWxscy4gCgoqIFRoZSBhaW0gb2YgU291cFggaXMgdG8gZXN0aW1hdGUgd2hhdCBmcmFjdGlvbiBvZiB0aGUgdHJhbnNjcmlwdHMgYXJlIGRlcml2ZWQgYXMgYW1iaWVudCBpbiBlYWNoIGRyb3BsZXQgYW5kIHRvIGdlbmVyYXRlIGEgY29ycmVjdGVkIGdlbmUgY291bnRzIG1hdHJpeCB3aXRoIHRoZSBjb250YW1pbmF0ZWQgY291bnRzIHJlbW92ZWQuIFRoZSBhbGdvcnRobSB0YWtlIHRoZSBmb2xsb3dpbmcgc3RlcHM6CiAgLSBJdCBmaXJzdCBjYWxjdWxhdGVzIHRoZSBleHByZXNzaW9uIHByb2ZpbGUgb2YgdGhlIHRvdGFsIGNvbnRhbWluYXRpb24gYnkgZXN0aW1hdGluZyB0aGUgYW1iaWVudCBSTkEgZXhwcmVzc2lvbiBmcm9tIHRoZSByYXcgY291bnRzLW1hdHJpeCBvYnRhaW5lZCBmcm9tIHRoZSBDZWxsUmFuZ2VyIG91dHB1dC4gUmVnYXJkbGVzcyBvZiB0aGUgdXNlciBjaG9pY2UsIGluIHRoaXMgc3RlcCB3ZSBhbHdheXMgdXRpbGl6ZSB0aGUgcmF3IGNvdW50cyBhcyB0aGlzIGRhdGEgY29udGFpbnMgaW5mb3JtYXRpb24gb2YgZW1wdHkgZHJvcGxldHMsIHdoaWNoIGlzIGFuIGV4Y2VsbGVudCBjYW5kaWRhdGUgdG8gYW5hbHl6ZSBjZWxsLWZyZWUgZHJvcGxldHMgdGhhdCBtYXkgY29udGFpbiBhbWJpZW50IFJOQSBmb3IgZWFjaCBnZW5lLiAoSWYgZm9yIHNvbWUgcmVhc29uIHRoZSByYXcgY291bnRzIGFyZSBub3QgYXZhaWxhYmxlLCBTb3VwWCB3aWxsIG5vdCBydW4sIGFuZCB0aGUgcGlwZWxpbmUgd2lsbCBjb250aW51ZSB3aXRob3V0IHRoZSBjb3JyZWN0aW9uIG9mIGFtYmllbnQgUk5BKS4KICAtIE9uY2UgdGhlIHRvdGFsIGNvbnRhbWluYXRpb24gaGFzIGJlZW4gZXN0aW1hdGVkLCBTb3VwWCBjYWxjdWxhdGVzIHRoZSBjZWxsIHNwZWNpZmljIGNvbnRhbWluYXRpb24gbGV2ZWwgYnkgdXNpbmcgdGhlIHByZXZpb3VzbHkgZm91bmQgY2VsbCBjbHVzdGVycy4gVGhlIHBvaW50IGhlcmUgaXMgdG8gZmluZCBhIHNldCBvZiBnZW5lcyBpbiBlYWNoIGNlbGwgdGhhdCBpcyBrbm93biBub3QgYmUgZXhwcmVzc2VkIGluIG90aGVycywgYW5kIHRoZW4gZXN0aW1hdGUgdGhlIGNvbnRhbWluYXRpb24gZnJhY3Rpb24gdXNpbmcgdGhlIGV4cHJlc3Npb24gb2YgdGhhdCBnaXZlbiBnZW5lIGluIGNlbGxzIGl0IGRvZXMgbm90IGJlbG9uZy4gSWYgeW91IGhhdmUgdG9vIGZldyBjbHVzdGVyIChkdWUgdG8gbGFjayBoaWdobHkgdmFyaWFibGUgZ2VuZXMgYW5kIGluc3VmZmljaWVudCBudW1iZXIgUEMgZGltZW5zaW9ucyksIHRoZW4gaXQgaXMgYWR2aXNlZCB0byBjaGFuZ2UgbnVtYmVyIG9mIFVNQVAgZGltZW5zaW9ucyA+MC44LiBUcnkgaXQgb3V0IGFuZCBzZWUgaWYgYW55dGhpbmcgaW1wcm92ZXMuIFVzdWFsbHksIGxvdyBudW1iZXIgb2YgY2x1c3RlcnMgc3VnZ2VzdHMgbG93LWNvbXBsZXhpdHkgZGF0YSAoZWl0aGVyIGJpb2xvZ2ljYWwgb3IgdGVjaG5pY2FsIHJlYXNvbnMpLiBSZW1lbWJlciB0aGF0IHlvdSBjYW4gYWxzbyBsZWF2ZSBvdXQgYW1iaWVudCBSTkEgY29ycmVjdGlvbiB3aGVuIGRlYWxpbmcgbG93LWNvbXBsZXhpdHkgaWYgaGlnaGVyIFVNQVAgZGltZW5zaW9ucyBkbyBub3QgaW1wcm92ZSBhbnl0aGluZy4KICAtIFdpdGggdGhlIGVzdGltYXRlZCBjb250YW1pbmF0aW9uIGZyYWN0aW9uIGFuZCB0aGUgYmFja2dyb3VuZCBleHByZXNzaW9uIHByb2ZpbGUgYXQgb3VyIGRpc3Bvc2FsLCB0aGUgY29udGFtaW5hdGVkIGNvdW50cyBmb3IgZWFjaCBnZW5lIHdpdGhpbiBlYWNoIGNlbGwgY2FuIHRoZW4gYmUgY29ycmVjdGVkLgoKKiBLZWVwIGluIG1pbmQgdGhhdCB3b3JraW5nIHdpdGggdGhlIHJhdyBjb3VudHMgbWF0cml4IG9ubHkgd2lsbCBhdXRvbWF0aWNhbGx5IGZpbHRlciBjZWxscy9kcm9wbGV0cyB0aGF0IGhhdmUgbGVzcyB0aGFuIDEwMCBnZW5lcy4gVGhpcyBpcyBhIGxlc3MgYWdncmVzc2l2ZSBmaWx0ZXJpbmcgd2hlbiBjb21wYXJlZCB0byB1c2luZyB0aGUgZmlsdGVyZWQgY291bnRzIG1hdHJpeCB3aGVyZSBDZWxscmFuZ2VyIGZpbHRlcmVkIG91dCBjZWxscy9kcm9wbGV0cyB0aGF0IGNvbnRhaWVkIDw1MDAgVU1Jcy4gRm9yIHRoaXMgcmVhc29uLCBkbyBub3QgYmUgc2hvY2tlZCB0byBmaW5kIGhpZ2hlciBhbWJpZW50IFJOQSBjb250YW1pbmF0aW9uIHdoZW4gd29ya2luZyB3aXRoIHRoZSByYXcgY291bnRzLiBUaGUgZGF0YSB3aWxsIGJlIHN1Y2Nlc3NmdWxseSBjb3JyZWN0ZWQgbW9zdCBvZiB0aGUgdGltZSAodW5sZXNzIHlvdSBhcmUgZGVhbGluZyB3aXRoIG1hbnkgZGVncmFkZWQgUk5BcyBkdWUgdG8gZmFpbGVkIGV4cGVyaW1lbnQpLgoKIyMjIyMgUmVzdWx0czogIyMjIyMKCiogQ29udGFtaW5hdGlvbiBEZW5zaXR5IHBsb3QgKEZpcnN0IHBsb3QpOiAgIAotIFJlcHJlc2VudGluZyB0aGUgcHJvYmFiaWxpdHkgZGlzdHJpYnV0aW9uIG9mIGVzdGltYXRlZCBjb250YW1pbmF0aW9uIGZyYWN0aW9uLiBUaGUgcHJvYmFiaWxpdHkgZGVuc2l0eSBpcyBjYWxjdWxhdGVkIGJ5IHRoZSBhZ2dyZWdhdGVkIHNldCBvZiBnZW5lcyBwZXIgY2VsbHMtY2x1c3RlciB0aGF0IGhhdmUgYmVlbiB1c2VkIHRvIGZpbmQgdGhlIGNvbnRhbWluYXRpb24gZnJhY3Rpb24uIFRoZSBmaW5hbCBjb250YW1pbmF0aW9uIGZyYWN0aW9uIGlzIHRoZW4gYXNzaWduZWQgdG8gdGhlIG9uZSB0aGF0IG9jY3VycyB3aXRoIHRoZSBoaWdoZXN0IHByb2JhYmlsaXR5IChpbmRpY2F0ZWQgd2l0aCBhIHZlcnRpY2FsIHJlZCBsaW5lKS4gQSBwcm9iYWJpbGl0eSBkaXN0cmlidXRpb24gd2l0aCBhIGZsYXQgbGluZSAobm8gY2xlYXIgcGVhaykgaW5kaWNhdGVzIGZhaWx1cmUgb2YgU291cFggYXMgbm9uZSBvZiB0aGUgc2V0cyBvZiBnZW5lcyBoYXZlIGEgcHJlZmVycmVkIGNvbnRhbWluYXRpb24gZnJhY3Rpb24sIHdoaWxlIHRydWUgZXN0aW1hdGVzIGFyZSBtb3JlIGxpa2VseSB0byBoYXZlIHRoZSBzYW1lIHByb2JhYmlsaXR5LgoKKiBCYXJwbG90OgogIC0gUmVwcmVzZW50aW5nIHRoZSBwZXJjZW50YWdlIG9mIGFtYmllbnQgUk5BIGRldGVjdGVkIGFuZCByZW1vdmVkIGZyb20gdGhlIGRhdGEuIEEgY29udGFtaW5hdGlvbiBsZXZlbCBvZiBhcm91bmQgMTAlIGlzIHR5cGljYWwgZm9yIG5vbi1udWNsZWkgZnJlc2ggdGlzc3VlIHNhbXBsZS4KCiogQWZmZWN0ZWQgTWFya2VycyBTb3VwIE1hcmtlcnMgKFVNQVApOiAKICAtIFJlcHJlc2VudGluZyB0aGUgZXhwcmVzc2lvbiBvZiBtYXJrZXIgY2FuZGlkYXRlcyB0aGF0IHdlcmUgdXNlZCBmb3IgdGhlIGVzdGltYXRpb24gb2YgdGhlIGNvbnRhbWluYXRpb24gZnJhY3Rpb24gYW5kIHRoZWlyIGxldmVsIG9mIGNvcnJlY3Rpb24gKHByZSBhbmQgcG9zdCBTb3VwIGNvcnJlY3Rpb24pLiBCeSBkZWZhdWx0LCB0b3AgMyBtYXJrZXJzIGFyZSB1c2VkIGZvciBwbG90dGluZywgYnV0IHRoZSB1c2VyIGlzIHByb3ZpZGVkIHdpdGggdGhlIG9wdGlvbiB0byBjaG9vc2UgYW55dGhpbmcgYmV0d2VlbiAwLTEwMC4gCgoqIEFmZmVjdGVkIFVzZXIgR2VuZXMgKFVNQVApOiAKICAtIFJlcHJlc2VudGluZyB0aGUgZXhwcmVzc2lvbiBvZiB1c2VyLWRlZmluZWQgZ2VuZXMgYW5kIGxldmVsIG9mIGNvcnJlY3Rpb24uIEZvciB0aGlzIHRvIHdvcmsgdGhlIHVzZXIgbXVzdCBmaWxsIGluIHRoZSBnZW5lcyBvZiBpbnRlcmVzdCBpbiB0aGUgZ2VuZS50eHQgZmlsZS4KICAKKiBNb3N0IEFmZmVjdGVkIEdlbmVzIChVTUFQKTogCiAgLSBSZXByZXNlbnRpbmcgdGhlIGV4cHJlc3Npb24gb2YgbW9zdC1hZmZlY3RlZCBnZW5lcyBhbmQgbGV2ZWwgb2YgY29ycmVjdGlvbi4gQXMgdGhlIG1vc3QtYWZmZWN0ZWQgZ2VuZXMgYXJlIG5vdCBleHByZXNzZWQgYnkgbWFueSBjZWxscywgdGhlc2UgcGxvdHMgbWlnaHQgbm90IGJlIHZlcnkgcmVwcmVzZW50YXRpdmUuIFRoaXMgb3B0aW9uIGlzIHR1bmVkIG9mZiBieSBkZWZhdWx0LCBidXQgdGhlIHVzZXIgbWF5IHR1cm4gaXQgb24gYW5kIHNlbGVjdCB0aGUgbnVtYmVyIHBsb3RzLgoKKiBDb2xvcnMgaW4gdGhlIFVNQVAgcGxvdHM6CiAgLSBSZWQgZG90cyAtIHRoZSBnZW5lIGlzIHN0cm9uZ2x5IGNvcnJlY3RlZCBpbiB0aGUgY2VsbAogIC0gV2hpdGUgZG90cyAtIHRoZSBnZW5lIGlzIHdlYWtseSBjb3JyZWN0ZWQgaW4gdGhlIGNlbGwKICAtIEdyZXkgZG90cyAtIE5vdGhpbmcgaGFwcGVuZWQgdG8gdGhhdCBjZWxsCmBgYHtyIFNvdXB4LCBmaWcuaGVpZ2h0PTYsIGZpZy53aWR0aD05LCBlY2hvPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQojIyMjIyMjIyMjIyMjIyMjIyMjIyBDaHVuayAjIyMjIyMjIyMjIyMjIyMjIyMjIyAKIyAvLyBUaGlzIGNodW5rIGVsaW1pbmF0ZXMgYW5kIGNvcnJlY3RzIGZvciBhbWJpZW50IFJOQSB1c2luZyBTb3VwWAojIC8vIEJhc2VkIG9uIHVzZXIgcGFyYW1ldGVycywgdGhlIGVmZmVjdCBvZiBhbWJpZW50IFJOQSBjb3JyZWN0aW9uIHdpbGwgYmUgZGlzcGxheWVkIGluIGEgVU1BUCBwcm9qZWN0aW9uCiMgLy8gQSBhbWJpZW50IFJOQSBjb3JyZWN0ZWQgcmF3IGNvdW50IG1hdHJpeCB3aWxsIGJlIHJldHVybmVkIGFuZCBzYXZlZCBvbiB1c2VyIGRlZmluZWQgcGF0aAojIyMjIyMjIyMjIyMjIyMjIyMjIyAgICAgICAjIyMjIyMjIyMjIyMjIyMjIyMjIyAKCmlmIChsb3cuY29tcGxleGl0eSA9PSAieWVzIiAmIHN0cl9sZW5ndGgobG93LmNvbXBsZXhpdHkpICE9IDApIHsgIyBJZiB3ZSBoYXZlIGxvdyBjb21wbGV4aXR5IGRhdGEgb3Igd3JvbmcgcGFyYW1ldGVyIGdpdmVuLCB0aGVuIFNvdXBYIHdpbGwgYmUgc2tpcHBlZAogIHByaW50KCJDb3JyZWN0aW9uIGZvciBhbWJpZW50IFJOQSB3aWxsIG5vdCBiZSBjYXJyaWVkIG91dCIpCn0gZWxzZSB7CiAgaWYgKHN0cl9sZW5ndGgoY291bnRzX3BhdGhfcmF3KSAhPSAwKSB7ICAjIElmIHdlIGhhdmUgYSByYXcgY291bnQgbWF0cml4IGRhdGEgYW5kIGxvdy5jb21wbGV4aXR5IHBhcmFtZXRlciBpcyBub3QgZ2l2ZW4gb3Igbm8sIHRoZW4gU291cFggd2lsbCBydW4KICAgIHNvYmpfbGlzdF9maWx0ZXJlZCA8LSBsaXN0KCkgIyBtYWtlIGVtcHR5IGxpc3QgdG8gYXBwZW5kIFNldXJhdCBTb3VweCBjbGVhbmVkIFNldXJhdCBvYmplY3RzIGluIHRoZSBsb29wIGJlbG93IChvbmx5IGluIGNhc2Ugd2UgdXNlIGRpZmZlcmVudCBhcHByb3VjaCkKICAgIGZvciAoaSBpbiAxOmxlbmd0aCh4ID0gc2FtcGxlX25hbWVzKSkgewogICAgICBzb2JqX2xpc3RbW2ldXVtbIm9yaWdpbmFsLmNvdW50cyJdXSA8LSBDcmVhdGVBc3NheU9iamVjdChjb3VudHMgPSBzb2JqX2xpc3RbW2ldXUBhc3NheXMkUk5BJGNvdW50cykgIyBrZWVwIG9yaWdpbmFsIGNvdW50IHRvIG1ha2UgY29tcGFyaXNvbiBmb3IgbGF0ZXIKICAgICAgIyBydW4gU291cHg6CiAgICAgIHNvdXBfY2hhbm5lbCA9IFNvdXBDaGFubmVsKGQxMHguZGF0YS5yYXdbW2ldXSwgc29ial9saXN0W1tpXV1AYXNzYXlzJFJOQSRjb3VudHMpICMgY3JlYXRlIHNvdXAgY2hhbm5lbHMgYnkgcGFzc2luZyBpbiB0aGUgcmF3IDEwWCBtYXRyaXggYW5kIHRoZSBTZXVyYXQgY291bnRzIG1hdHJpeAogICAgICBzb3VwX2NoYW5uZWwgPSBzZXRDbHVzdGVycyhzb3VwX2NoYW5uZWwsIHNvYmpfbGlzdFtbaV1dJHNldXJhdF9jbHVzdGVycykgIyBXZSBzZXQgdGhlIGNsdXN0ZXJzIHByZXZpb3VzbHkgZm91bmQsIGFzIHRoZXNlIGNsdXN0ZXJzIGFyZSBlc3NlbnRpYWwgdG8gZmluZCBoaWdobHkgc3BlY2lmaWMgbWFya2VyIGdlbmVzLiAgIAogICAgICBzb3VwX2NoYW5uZWwgPSBhdXRvRXN0Q29udChzb3VwX2NoYW5uZWwsIGRvUGxvdD1UUlVFLCBwcmlvclJobyA9IDAuMDUsIHByaW9yUmhvU3RkRGV2ID0gMC4xLCByaG9NYXhGRFIgPSAwLjIsIGZvcmNlQWNjZXB0PVRSVUUpICMgZXN0aW1hdGUgdGhlIGNvbnRhbWluYXRpb24gZnJhY3Rpb24gdXNpbmcgbWFya2VycyBmcm9tIGNsdXN0ZXJzCiAgICAgIG91dCA9IGFkanVzdENvdW50cyhzb3VwX2NoYW5uZWwsIHJvdW5kVG9JbnQgPSBUUlVFKSAjIEZyb20gdGhlIHNvdXAgY2hhbm5lbCB3ZSBnZXQgdGhlIGFkanVzdGVkIGNvdW50cyBtYXRyaXggYW5kIHJvdW5kIGl0IHRvIHRoZSBuZWFyZXN0IGludGVnZXIuLi4uLi4uLiAjIyMjIyMjIyMjIFNBRkUgVEhFIE9VVFBVVFMgT0YgQU1CSUVOVCBSTkEKICAKICAgICAgIyBTYXZlIHRoZSBBbWJpZW50IFJOQSBjb3JyZWN0ZWQgTWF0cml4CiAgICAgIGlmIChkaXIuZXhpc3RzKGZpbGUucGF0aChwYXN0ZShwYXJlbnRfZGlyZWN0b3J5LCBwYXN0ZShzYW1wbGVfcGF0aFtpXSwgIi9uZXctb3V0cy9jb3VudHMiLCBzZXAgPSAiIiksIHNlcCA9ICIvIikpKSkgewogICAgICAgIHdyaXRlMTB4Q291bnRzKHBhc3RlKHBhcmVudF9kaXJlY3RvcnksIHBhc3RlKHNhbXBsZV9wYXRoW2ldLCAiL25ldy1vdXRzL2NvdW50cy9Tb3VwQ29ycmVjdGVkQ291bnRzIiwgc2VwID0gIiIpLCBzZXAgPSAiLyIpLCBvdXQsIHZlcnNpb24gPSAiMyIsIG92ZXJ3cml0ZSA9IFRSVUUpCiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGRpci5jcmVhdGUoZmlsZS5wYXRoKHBhc3RlKHBhcmVudF9kaXJlY3RvcnksIHBhc3RlKHNhbXBsZV9wYXRoW2ldLCAiL25ldy1vdXRzL2NvdW50cyIsIHNlcCA9ICIiKSwgc2VwID0gIi8iKSksIHJlY3Vyc2l2ZSA9IFRSVUUpCiAgICAgICAgICB3cml0ZTEweENvdW50cyhwYXN0ZShwYXJlbnRfZGlyZWN0b3J5LCBwYXN0ZShzYW1wbGVfcGF0aFtpXSwgIi9uZXctb3V0cy9jb3VudHMvU291cENvcnJlY3RlZENvdW50cyIsIHNlcCA9ICIiKSwgc2VwID0gIi8iKSwgb3V0LCB2ZXJzaW9uID0gIjMiLCBvdmVyd3JpdGUgPSBUUlVFKQogICAgICAgICAgfQogIAogICAgICAjIHVwZGF0ZSB0aGUgUk5BIGNvdW50cyB3aXRoIHRoZSBzb3VwIGNvcnJlY3RlZCBtYXRyaXghISEKICAgICAgIyBOT1RFIHRoYXQgd2UgZG8gdGhpcyB0d2ljZSwgZm9yIHR3byBzZXBhcmF0ZSBzbG90cyAoZXZlbiB0aG91Z2ggaXQgaXMgdGhlIHNhbWUpLCBiZWNhdXNlIHRoZSBkZXZlbG9wZXJzIG9mIFNldXJhdF92NSB0aG91Z2h0IGl0IHdhcyBjb29sIHRvIEZVQ0sgdGhpbmdzIHVwIQogICAgICAjIElmIHlvdSBhcmUgdXBkYXRpbmcgdGhlIFNldXJhdCBwYWNrYWdlIGluIHRoZSBmdXR1cmUsIHBsZWFzZSBtYWtlIHN1cmUgdGhlIHR3byBsaW5lIGJlbG93IGFyZSBjb21wYXRpYmxlLiBJZiBub3QsIHRoZW4gZ2V0IHJlYWR5IGZvciBzb21lIEZVQ0tJTkcgc2xlZXBsZXNzIG5pZ2h0cy4uLgogICAgICBzb2JqX2xpc3RbW2ldXUBhc3NheXMkUk5BJGNvdW50cyA8LSBvdXQgCiAgICAgICNzb2JqX2xpc3RbW2ldXUBhc3NheXMkUk5BQGxheWVycyRjb3VudHMgPC0gb3V0ICMgZm9yICBzdWVyYXR2NQoKICAgICAgIyBBZGQgdGhlIGNsdXN0ZXJpbmcgY29vcmRpbmF0ZXMgb2Ygb3VyIFNldXJhdCBvYmplY3RzIHRvIHRoZSBTb3VwIGNoYW5uZWwKICAgICAgVU1BUDEgPC0gZGF0YS5mcmFtZShzb2JqX2xpc3RbW2ldXUByZWR1Y3Rpb25zW1sidW1hcCJdXUBjZWxsLmVtYmVkZGluZ3MpWyAsIDFdICMgZXh0cmFjdCB0aGUgVU1BUCBjb29yZGluYXRlcyBmcm9tIFNldXJhdCBvYmplY3QKICAgICAgVU1BUDIgPC0gZGF0YS5mcmFtZShzb2JqX2xpc3RbW2ldXUByZWR1Y3Rpb25zW1sidW1hcCJdXUBjZWxsLmVtYmVkZGluZ3MpWyAsIDJdCiAgICAgIHNvdXBfY2hhbm5lbCRtZXRhRGF0YVtbIlVNQVAxIl1dIDwtIFVNQVAxICMgQXBwZW5kIHRoZSBVTUFQIGNvb3JkaW5hdGVzIHRvIHRoZSBzb3VwX2NoYW5uZWwkbWV0YURhdGEKICAgICAgc291cF9jaGFubmVsJG1ldGFEYXRhW1siVU1BUDIiXV0gPC0gVU1BUDIKICAgICAgc291cF9jaGFubmVsW1siRFIiXV0gPC0gdW5saXN0KGMoIlVNQVAxIiwgIlVNQVAyIikpICMgYWRkIGEgKGNoYXJhY3RlciBbMl0pIG9mICJVTUFQMSIiVU1BUDIiIHRvIHRoZSBzb3VwX2NoYW5uZWwKICAgICAgc291cF9tZXRhZGF0YSA8LSBzb3VwX2NoYW5uZWwkbWV0YURhdGEgIyBzb3VwIGNoYW5uZWwgbWV0YWRhdGEgZGF0YSBzYXZpbmcKICAKICAgICAgIyBDYWxjdWxhdGUgdGhlIHBlcmNlbnRhZ2Ugb2YgY29udGFtaW5hdGVkIFJOQSAoVU1JKSByZW1vdmUKICAgICAgcGVyY2VudGFnZV9jb250YW1pbmF0aW9uIDwtIHBhc3RlKCJQZXJjZW50YWdlIG9mIEFtYmllbnQgUk5BIChVTUkpIHJlbW92ZWQ6IiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJvdW5kKCgxIC0gc3VtKHNvYmpfbGlzdFtbaV1dQGFzc2F5cyRSTkEkY291bnRzKS9zdW0oc29ial9saXN0W1tpXV1AYXNzYXlzJG9yaWdpbmFsLmNvdW50c0Bjb3VudHMpKSAqIDEwMCwgZGlnaXRzID0gMiksIHNlcCA9ICIgIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhc3RlKHNvYmpfbGlzdFtbaV1dQG1ldGEuZGF0YVsxLDFdKSkgCiAgICAgIHByaW50KHBlcmNlbnRhZ2VfY29udGFtaW5hdGlvbikKICAKICAgICAgIyBNYWtlIGRhdGEgZnJhbWUgb2YgYW1iaWVudCBSTkEgY29udGFtaW5hdGlvbiBsZXZlbHMgYW5kIG1ha2UgYmFycGxvdAogICAgICBkYXRhLmZyYW1lLmNvbnQgPC0gZGF0YS5mcmFtZShzYW1wbGVfbmFtZXMsIHJvdW5kKCgxIC0gc3VtKHNvYmpfbGlzdFtbaV1dQGFzc2F5cyRSTkEkY291bnRzKS9zdW0oc29ial9saXN0W1tpXV1AYXNzYXlzJG9yaWdpbmFsLmNvdW50c0Bjb3VudHMpKSAqIDEwMCwgZGlnaXRzID0gMikpCiAgICAgICMgcGxvdCBiYXJzCiAgICAgIFMxIDwtIGdncGxvdChkYXRhLmZyYW1lLmNvbnQsIGFlcyh4ID0gZmFjdG9yKHNhbXBsZV9uYW1lcywgbGV2ZWxzID0gc2FtcGxlX25hbWVzKSwgeSA9IHJvdW5kKCgxIC0gc3VtKHNvYmpfbGlzdFtbaV1dQGFzc2F5cyRSTkEkY291bnRzKS9zdW0oc29ial9saXN0W1tpXV1AYXNzYXlzJG9yaWdpbmFsLmNvdW50c0Bjb3VudHMpKSAqIDEwMCwgZGlnaXRzID0gMikpKSArIAogICAgICAgIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiLCBwb3NpdGlvbiA9ICJkb2RnZSIsIGFscGhhID0gMC41LCBjb2xvdXIgPSAiYmxhY2siLCB3aWR0aCA9IDAuNSkgKyAKICAgICAgICB5bGltKDAsIHJvdW5kKCgxIC0gc3VtKHNvYmpfbGlzdFtbaV1dQGFzc2F5cyRSTkEkY291bnRzKS9zdW0oc29ial9saXN0W1tpXV1AYXNzYXlzJG9yaWdpbmFsLmNvdW50c0Bjb3VudHMpKSAqIDEwMCArIDUpKSArIAogICAgICAgIGdlb21fdGV4dChsYWJlbCA9IHJvdW5kKCgxIC0gc3VtKHNvYmpfbGlzdFtbaV1dQGFzc2F5cyRSTkEkY291bnRzKS9zdW0oc29ial9saXN0W1tpXV1AYXNzYXlzJG9yaWdpbmFsLmNvdW50c0Bjb3VudHMpKSAqIDEwMCwgZGlnaXRzID0gMiksIHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2Uod2lkdGggPSAxKSx2anVzdCA9IC0wLjUsIHNpemUgPSA0KSArICMgdmFsdWUgYWJvdmUgYmFyCiAgICAgICAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gMTAsIGxpbmV0eXBlPSJkYXNoZWQiLCBjb2xvciA9ICJyZWQiLCBzaXplPTEpICsKICAgICAgICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSA1LCBsaW5ldHlwZT0iZGFzaGVkIiwgY29sb3IgPSAib3JhbmdlIiwgc2l6ZT0xKSArIAogICAgICAgIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDIuNSwgbGluZXR5cGU9ImRhc2hlZCIsIGNvbG9yID0gImdyZWVuIiwgc2l6ZT0xKSArCiAgICAgICAgdGhlbWVfYncoKSArIAogICAgICAgIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gMCwgaGp1c3QgPSAwLjUsIHNpemUgPSA5LjUpKSArIAogICAgICAgIHRoZW1lKHBhbmVsLmdyaWQubWFqb3IgPSBlbGVtZW50X2JsYW5rKCksIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2JsYW5rKCkpICsgCiAgICAgICAgbGFicyh4PSIiLCB5PSJBbWJpZW50IFJOQSBSZW1vdmVkICglKSIpICsgc2NhbGVfZmlsbF9ncmV5KCkgKwogICAgICAgIHRoZW1lKGFzcGVjdC5yYXRpbyA9IDUuNSkgIyArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9IGMoMC4xLCAwLjc1KSkKICAgICAgcHJpbnQoUzEpCiAgCiAgICAgICMgQW5hbHl6ZSBvdXRwdXQgYW5kIHBsb3QgbWFya2VycywgcmFuZG9tIGdlbmVzLCBtb3N0IGFmZmVjdGVkLCBvciB1c2VyIGdpdmVuIG1hcmtlcnM6CiAgICAgICMgQnV0IGZpcnN0IHdlIHNldHVwIHRoZSBudW1iZXIgb2YgcGxvdHMgZGVmaW5lZCBieSAgdXNlciBvcHRpb25zIG9yIGRlZmF1bHQKICAgICAgaWYgKGlzLm5hKG4ubWFya2Vycy5nZW5lcykgPT0gVFJVRSkgewogICAgICAgIG1hcmtlcnNfYnlfc291cCA8LSBzb3VwX2NoYW5uZWxbWyJmaXQiXV1bWyJtYXJrZXJzVXNlZCJdXVtbImdlbmUiXV1bMTozXSAjIDMgbWFya2VycyB1c2VkIGJ5IGJ5IGRlZmF1bHQKICAgICAgfSBlbHNlIHsKICAgICAgICBtYXJrZXJzX2J5X3NvdXAgPC0gc291cF9jaGFubmVsW1siZml0Il1dW1sibWFya2Vyc1VzZWQiXV1bWyJnZW5lIl1dWzE6bi5tYXJrZXJzLmdlbmVzXSAjIG9yIHVzZXIgcGFyYW1ldGVyCiAgICAgIH0KICAgICAgaWYgKGlzLm5hKG4uaGlnaGx5X2FmZmVjdGVkLmdlbmVzKSA9PSBUUlVFKSB7CiAgICAgICAgZXhwX2JlZm9yZS5zb3VwIDwtIG5hbWVzKHRhaWwoc29ydCgocm93U3Vtcyhzb3VwX2NoYW5uZWwkdG9jID4gMCkgLSByb3dTdW1zKG91dCA+IDApKS9yb3dTdW1zKHNvdXBfY2hhbm5lbCR0b2MgPiAwKSksIG4gPSAwKSkgCiAgICAgIH0gZWxzZSB7CiAgICAgICAgZXhwX2JlZm9yZS5zb3VwIDwtIG5hbWVzKHRhaWwoc29ydCgocm93U3Vtcyhzb3VwX2NoYW5uZWwkdG9jID4gMCkgLSByb3dTdW1zKG91dCA+IDApKS9yb3dTdW1zKHNvdXBfY2hhbm5lbCR0b2MgPiAwKSksIG4gPSBuLmhpZ2hseV9hZmZlY3RlZC5nZW5lcykpIAogICAgICAgIH0KICAgICAgCiAgICAgICMgcHJpbnQoZXhwX2JlZm9yZS5zb3VwKQogICAgICAjIHJhZG5vbV9nZW5lcyA8LSBzYW1wbGUoeCA9IHJvd25hbWVzKGRhdGEuZnJhbWUoc291cF9jaGFubmVsJHRvYykpLCBzaXplID0gMTAsIHJlcGxhY2UgPSBGQUxTRSkgIyA0IFJhbmRvbWx5IHNlbGVjdGVkIGdlbmVzIHRvIGNoZWNrIGFmZmVjdGlvbiBhZnRlciBjb3JyZWN0aW9uCgogICAgICAjIHBsb3QgdGhlIG1vc3QgbWFya2VyIGdlbmVzIGJlZm9yZSBhbmQgYWZ0ZXIgY29ycmVjdGlvbjoKICAgICAgaWYgKGxlbmd0aChjYW5vbmljYWxfbWFya2VycykgPiAwIHwgKG4ubWFya2Vycy5nZW5lcyA+IDAgJiBsZW5ndGgoY2Fub25pY2FsX21hcmtlcnMpID4gMCkpIHsKICAgICAgICBpZiAobi5tYXJrZXJzLmdlbmVzID4gMCAmIGlzLm5hKG4ubWFya2Vycy5nZW5lcykgPT0gRkFMU0UpIHsKICAgICAgICAgIGZvciAoaiBpbiBtYXJrZXJzX2J5X3NvdXApewogICAgICAgICAgICBzb3VwX21ldGFkYXRhW2pdID0gc291cF9jaGFubmVsJHRvY1tqLCBdIAogICAgICAgICAgICAjIFBsb3QKICAgICAgICAgICAgcHJpbnQocGxvdE1hcmtlck1hcChzb3VwX2NoYW5uZWwsIGosIHBvaW50U2l6ZSA9IDEuNSkgKyAKICAgICAgICAgICAgICAgICAgICBnZ3RpdGxlKHBhc3RlKCJFeHByZXNzaW9uZyBvZjogIiwgcGFzdGUoaiwgIkFzc3VtaW5nIEFsbCBDZWxscyBhcmUgU291cCIsIHNlcCA9ICIgKFNvdXAgbWFya2VyKSAtICIpKSwgc3VidGl0bGUgPSBzb2JqX2xpc3RbW2ldXUBtZXRhLmRhdGFbMSwxXSkgKyAKICAgICAgICAgICAgICAgICAgICB5bGFiKCJVTUFQIDEiKSArIHhsYWIoIlVNQVAgMiIpKQogICAgICAgICAgICBwcmludChwbG90Q2hhbmdlTWFwKHNvdXBfY2hhbm5lbCwgb3V0LCBqLCBwb2ludFNpemUgPSAxLjUpICsgCiAgICAgICAgICAgICAgICAgICAgZ2d0aXRsZShwYXN0ZSgiQ2hhbmdlIGluIEV4cHJlc3Npb24gb2Y6ICIsIHBhc3RlKGosICJQb3N0IFNvdXAgQ29ycmVjdGlvbiIsIHNlcCA9ICIgKFNvdXAgbWFya2VyKSAtICIpKSwgc3VidGl0bGUgPSBzb2JqX2xpc3RbW2ldXUBtZXRhLmRhdGFbMSwxXSkgKyAKICAgICAgICAgICAgICAgICAgICB5bGFiKCJVTUFQIDEiKSArIHhsYWIoIlVNQVAgMiIpKQogICAgICAgICAgICB9CiAgICAgICAgICB9IGVsc2UgeyAjIEVoLCBzb21lIHNsb3BweSBjb2Rpbmcgd2l0aCBlbHNlIGFuZCBubyBhcmd1bWVudAogICAgICAgICAgICB9CiAgICAgICAgZm9yIChqIGluIGNhbm9uaWNhbF9tYXJrZXJzKSB7CiAgICAgICAgICBzb3VwX21ldGFkYXRhW2pdID0gc291cF9jaGFubmVsJHRvY1tqLCBdICMgYWRkIHRoZSBnZW5lcyB0byBiZSBhbmFseXplZCB0b3QgdGhlIG1ldGFkYXRhIGNvbHVtbnMKICAgICAgICAgICAjIGlmIHdlIGFzc3VtZWQgYWxsIGNlbGxzIHdlcmUgbm90aGluZyBidXQgc291cCwgd2hpY2ggY2VsbHMgc3RpbGwgc2hvdyBoaWdoZXIgdGhhbiBleHBlY3RlZCBleHByZXNzaW9uIGZvciB0aGUgZ2VuZSAoVFJVRSA9IGV4cHJlc3Npb24gbGV2ZWxzIGhpZ2hlciB0aGFuIGV4cGVjdGVkIGlmIGNlbGwgd2FzIGp1c3Qgc291cCwgc28gbGlrZWx5IHJlYWwgZXhwcmVzc2lvbikuIFRoaXMganVzdCBnaXZlcyB1cyBhbiBpZGVhIG9mIHNvdXAgZXhwcmVzc2lvbiwgdGhpcyBpcyBOT1QgYSBmb3JtYWwgYW5hbHlzaXMgdXNlZCBmb3IgcmVtb3ZpbmcgdGhlIHNvdXAgUk5BLgogICAgICAgICAgcHJpbnQocGxvdE1hcmtlck1hcChzb3VwX2NoYW5uZWwsIGosIHBvaW50U2l6ZSA9IDEuNSkgKyAKICAgICAgICAgICAgICAgICAgZ2d0aXRsZShwYXN0ZSgiRXhwcmVzc2lvbmcgb2Y6ICIsIHBhc3RlKGosICJBc3N1bWluZyBBbGwgQ2VsbHMgYXJlIFNvdXAiLCBzZXAgPSAiIChtYXJrZXIpIC0gIikpLCBzdWJ0aXRsZSA9IHNvYmpfbGlzdFtbaV1dQG1ldGEuZGF0YVsxLDFdKSArIAogICAgICAgICAgICAgICAgICB5bGFiKCJVTUFQIDEiKSArIHhsYWIoIlVNQVAgMiIpKQogICAgICAgICAgIyBDaGFuZ2UgaW4gZXhwcmVzc2lvbiBhZnRlciBTb3VwIGNvcnJlY3Rpb24KICAgICAgICAgIHByaW50KHBsb3RDaGFuZ2VNYXAoc291cF9jaGFubmVsLCBvdXQsIGosIHBvaW50U2l6ZSA9IDEuNSkgKyAKICAgICAgICAgICAgICAgICAgZ2d0aXRsZShwYXN0ZSgiQ2hhbmdlIGluIEV4cHJlc3Npb24gb2Y6ICIsIHBhc3RlKGosICJQb3N0IFNvdXAgQ29ycmVjdGlvbiIsIHNlcCA9ICIgKG1hcmtlcikgLSAiKSksIHN1YnRpdGxlID0gc29ial9saXN0W1tpXV1AbWV0YS5kYXRhWzEsMV0pICsgCiAgICAgICAgICAgICAgICAgIHlsYWIoIlVNQVAgMSIpICsgeGxhYigiVU1BUCAyIikpCiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsgIyBpZiBtYXJrZXJzIGFyZSBub3QgcHJvdmlkZWQgYnkgdGhlIHVzZXIsIHRoZW4gcGxvdCB0aGUgdG9wIDUgbWFya2VyIGdlbmVzIHVzZWQgYnkgU291cFgKICAgICAgICAgIGZvciAoaiBpbiBtYXJrZXJzX2J5X3NvdXApewogICAgICAgICAgICBzb3VwX21ldGFkYXRhW2pdID0gc291cF9jaGFubmVsJHRvY1tqLCBdIAogICAgICAgICAgICAjIFBsb3QKICAgICAgICAgICAgcHJpbnQocGxvdE1hcmtlck1hcChzb3VwX2NoYW5uZWwsIGosIHBvaW50U2l6ZSA9IDEuNSkgKyAKICAgICAgICAgICAgICAgICAgICBnZ3RpdGxlKHBhc3RlKCJFeHByZXNzaW9uZyBvZjogIiwgcGFzdGUoaiwgIkFzc3VtaW5nIEFsbCBDZWxscyBhcmUgU291cCIsIHNlcCA9ICIgKFNvdXAgbWFya2VyKSAtICIpKSwgc3VidGl0bGUgPSBzb2JqX2xpc3RbW2ldXUBtZXRhLmRhdGFbMSwxXSkgKyAKICAgICAgICAgICAgICAgICAgICB5bGFiKCJVTUFQIDEiKSArIHhsYWIoIlVNQVAgMiIpKQogICAgICAgICAgICBwcmludChwbG90Q2hhbmdlTWFwKHNvdXBfY2hhbm5lbCwgb3V0LCBqLCBwb2ludFNpemUgPSAxLjUpICsgCiAgICAgICAgICAgICAgICAgICAgZ2d0aXRsZShwYXN0ZSgiQ2hhbmdlIGluIEV4cHJlc3Npb24gb2Y6ICIsIHBhc3RlKGosICJQb3N0IFNvdXAgQ29ycmVjdGlvbiIsIHNlcCA9ICIgKFNvdXAgbWFya2VyKSAtICIpKSwgc3VidGl0bGUgPSBzb2JqX2xpc3RbW2ldXUBtZXRhLmRhdGFbMSwxXSkgKyAKICAgICAgICAgICAgICAgICAgICB5bGFiKCJVTUFQIDEiKSArIHhsYWIoIlVNQVAgMiIpKQogICAgICAgICAgICB9CiAgICAgICAgICB9CiAgCiAgICAgICMgcGxvdCB0aGUgbW9zdCBhZmZlY3RlZCBnZW5lcyBiZWZvcmUgYW5kIGFmdGVyIGNvcnJlY3Rpb24gCiAgICAgIGZvciAoaiBpbiBleHBfYmVmb3JlLnNvdXApIHsKICAgICAgICBzb3VwX21ldGFkYXRhW2pdID0gc291cF9jaGFubmVsJHRvY1tqLCBdIAogICAgICAgICNnZ3Bsb3Qoc291cF9tZXRhZGF0YSwgYWVzKFVNQVAxLCBVTUFQMikpICsgZ2VvbV9wb2ludChhZXMoY29sb3VyID0gQ0QzRSA+IDApLCBzaXplPTAuMikgKyBnZ3RpdGxlKHBhc3RlKCJFeHByZXNzaW9uZyBvZjogIiwgcGFzdGUoaiwgIlByZSBTb3VwIENvcnJlY3Rpb24iLCBzZXAgPSAiIC0gIikpLCBzdWJ0aXRsZSA9IHNvYmpfbGlzdFtbMl1dQG1ldGEuZGF0YVsxLDFdKSArIHlsYWIoIlVNQVAgMSIpICsgeGxhYigiVU1BUCAyIikKICAgICAgICBwcmludChwbG90TWFya2VyTWFwKHNvdXBfY2hhbm5lbCwgaiwgcG9pbnRTaXplID0gMSkgKyAKICAgICAgICAgICAgICAgIGdndGl0bGUocGFzdGUoIkV4cHJlc3Npb25nIG9mOiAiLCBwYXN0ZShqLCAiQXNzdW1pbmcgQWxsIENlbGxzIGFyZSBTb3VwIiwgc2VwID0gIiAoTW9zdCBhZmZlY3RlZCkgLSAiKSksIHN1YnRpdGxlID0gc29ial9saXN0W1tpXV1AbWV0YS5kYXRhWzEsMV0pICsgCiAgICAgICAgICAgICAgICB5bGFiKCJVTUFQIDEiKSArIHhsYWIoIlVNQVAgMiIpKQogICAgICAgIHByaW50KHBsb3RDaGFuZ2VNYXAoc291cF9jaGFubmVsLCBvdXQsIGopICsgCiAgICAgICAgICAgICAgICBnZ3RpdGxlKHBhc3RlKCJDaGFuZ2UgaW4gRXhwcmVzc2lvbiBvZjogIiwgcGFzdGUoaiwgIlBvc3QgU291cCBDb3JyZWN0aW9uIiwgc2VwID0gIiAoTW9zdCBhZmZlY3RlZCkgLSAiKSksIHN1YnRpdGxlID0gc29ial9saXN0W1tpXV1AbWV0YS5kYXRhWzEsMV0pICsgCiAgICAgICAgICAgICAgICB5bGFiKCJVTUFQIDEiKSArIHhsYWIoIlVNQVAgMiIpKQogICAgICAgIH0KICAgIH0KICB9IGVsc2UgeyAjIGVsc2Ugd2Ugbm90IHJ1biBzb3VweCBpZiB3ZSBkbyBub3QgaGF2ZSBhIHJhdyBjb3VudCBtYXRyaXggZm9yIHRoZSBjYWxjdWxhdGlvbiBvZiBhbWJpZW50IFJOQQogICAgcHJpbnQoIkR1ZSB0byBsYWNrIG9mIHJhdyBjb3VudCBtYXRyaXgsIGNvcnJlY3Rpb24gZm9yIGFtYmllbnQgUk5BIHdpbGwgbm90IGJlIGNhcnJpZWQgb3V0IikKICAgIH0KICB9CmBgYAoKIyMjIyBFeHRlbnNpdmUgZmlsdGVyaW5nICMjIyMKCiMjIyMjIERlc2NyaXB0aW9uOiAjIyMjIwoKKiBCeSBkZWZhdWx0LCB3ZSBhdXRvbWF0aWNhbGx5IGZpbHRlciBvdXQgY2VsbHMgd2l0aCBhIHBlcmNlbnRhZ2Ugb2YgTVQgcmVhZHMgYWJvdmUgMTAlLCB3aXRoIGdlbmUgYW5kIHRyYW5zY3JpcHQgY291bnRzIGJlbG93IHRoZSAyJSBxdWFudGlsZSBhcyBhIGxvd2VyIGxpbWl0LiBObyBmaWx0ZXJpbmcgaXMgYXBwbGllZCBvbiB0aGUgaGlnaGVyIGxpbWl0IGFzIHRoZXNlIGNlbGxzIGNvdWxkIHJlcHJlc2VudCBkb3VibGV0cyB0aGF0IHdlIHdhbnQgdG8gY2xhc3NpZnkgYnkgRG91YmxldEZpbmRlciBpbnN0ZWFkIG9mIHJlbW92aW5nIHRoZW0gYnkgZm9yY2UuIEhvd2V2ZXIsIGlmIHRoZSB1c2VyIGhhcyBwcmlvciBrbm93bGVkZ2Ugb24gdGhlIGRhdGFzZXQsIGZpbHRlcmluZyBjYW4gYWxzbyBiZSBhcHBsaWVkIGJ5IHVzZXItZGVmaW5lZCBjdXRvZmYgdmFsdWVzIGZvciB0aGUgbnVtYmVyIG9mIGdlbmVzLCB0cmFuc2NyaXB0cyBhbmQgcGVyY2VudGFnZSBvZiBNVCByZWFkcy4gQWRkaXRpb25hbGx5LCB0aGUgdXNlciBtYXkgYWxzbyBhZGp1c3QgdGhlIHVwcGVyIGFuZCBsb3dlciBxdWFudGlsZXMgZm9yIHRoZSBwYXJhbWV0ZXJzIG1lbnRpb25lZCBhYm92ZS4gSXQgaXMgaW1wb3J0YW50IHRvIGNvbnNpZGVyIHRoYXQgYnkgcmVtb3ZpbmcgY2VsbCBpbiB0aGUgdXBwZXIgbGltaXQgYnkgdXNlci1kZWZpbmVkIGN1dG9mZiB2YWx1ZXMgb3IgcXVhbnRpbGVzLCB0aGVyZSBpcyBhIGdvb2QgY2hhbmNlIHRoYXQgdHJ1ZSBkb3VibGV0cyBhcmUgYmVpbmcgcmVtb3ZlZCBiZWZvcmUgaWRlbnRpZmllZCBpbiBhbiBhbGdvcml0aG1pYyBmYXNoaW9uLgoKKiBOb3RlIHRoYXQgb3VyIGRlZmF1bHQgcGFyYW1ldGVycyBoYXZlIGJlZW4gcGVyZm9ybWluZyB3ZWxsIGluIGhpZ2ggY29tcGxleGl0eSAocG9yY2luZSBpbGV1bSBhbmQgY29sb24gdGlzc3VlLCB3aXRoIGltbXVuZSkgYW5kIGxvdyBjb21wbGV4aXR5IGRhdGEgKHBvcmNpbmUgaWxldW0gb3JnYW5vaWQpIHdpdGhvdXQgbG9vc2luZyBtYW55IGNlbGwtdHlwZXMgKGluY2x1ZGluZyBzb21lIHJhcmUgaW1tdW5lIGNlbGxzIHdpdGggbG93IG51bWJlciBvZiBnZW5lcy90cmFuc2NyaXB0cykuCgojIyMjIyBSZXN1bHRzOiAjIyMjIwoKKiBOb3cgdGFrZSBhIGxvb2sgaW4gdGhlIGNodW5rIGJlbG93Li4uIGhvdyBtYW55IGNlbGxzIGRvIHlvdSBoYXZlPyBJcyBpdCBzaWduaWZpY2FudGx5IGxvd2VyIHRoYW4gYmVmb3JlPwogIC0gKFRoZSBjZWxscyBhcmUgY2FsbGVkICdzYW1wbGVzJykuCiAgLSAoSWdub3JlIHRoZSBpbmZsYXRlZCBudW1iZXIgb2YgJ2ZlYXV0dXJlcycuIFRoZXNlIGFyZSB0aGUgbnVtYmVyIG9mIGdlbmVzIGZyb20gdHdvIGFzc2F5cyBpbiBTZXVyYXQpLgpgYGB7ciBkYXRhIGZpbHRlcmluZywgZmlnLmhlaWdodD01LCBmaWcud2lkdGg9MTIsIGVjaG89RkFMU0UsIHdhcm5pbmc9RkFMU0V9CiMjIyMjIyMjIyMjIyMjIyMjIyMjIENodW5rICMjIyMjIyMjIyMjIyMjIyMjIyMjIAojIC8vIFRoaXMgY2h1bmsgcGVyZm9ybXMgYW4gZXh0ZW5zaXZlIGZpbHRlcmluZyBiYXNlZCBvbiB1c2VyIHBhcmFtZXRlcnMgKG9yIGRlZmF1bHQgaWYgbm90IHNwZWNpZmllZCkKIyAvLyBuRmVhdHVyZV9STkEgKG5HZW5lcyksIG5Db3VudF9STkEgKG5VTUlzKSBhbmQgTVQgcGVyY2VudGFnZSB3aWxsIGJlIGNvbnNpZGVyZWQKIyAvLyBCeSBkZWZhdWx0IDItOTglIHF1YW50aWxlIGFyZSBjb25zaWRlcmVkIGZvciB0aGUgcGFyYW1ldGVycyBtZW50aW9uZWQgYWJvdmUgd2l0aCBwZXJjZW50Lm10IDwgMTAKIyAvLyBDZWxsIHdpbGwgYmUgcmUtY2x1c3RlcmVkIGluIGNhc2UgdXNlciBkZWZpbmVkIHBhcmFtZXRlcnMgYXJlIHRvbyBleHRyZW1lIChyZXN1bHRpbmcgaW4gbG9zcyBvZiBtYW55IGNlbGxzKQojIyMjIyMjIyMjIyMjIyMjIyMjIyAgICAgICAjIyMjIyMjIyMjIyMjIyMjIyMjIyAKCiMjIyMjIyMjIyMgRnVuY3Rpb24gIyMjIyMjIyMjIyAKIyAvLyBUaGlzIGZ1bmN0aW9uIGZpbHRlcnMgYW5kIHJldHVybnMgYSBjbGVhbmVkIHVwIFNldXJhdCBvYmplY3QKIyAvLyBJbnB1dCBmaWxlIG11c3QgYmUgYSB2ZWN0b3Igb2YgU2V1cmF0IG9iamVjdHMKZXh0X2ZpbHRlcmluZyA8LSBmdW5jdGlvbihzb2JqKSB7CiAgaWYgKGlzLm5hKGZlYXR1cmVMT1cpICE9IFRSVUUgfCBpcy5uYShjb3VudExPVykgIT0gVFJVRSB8IGlzLm5hKGZlYXR1cmVISUdIKSAhPSBUUlVFIHwgaXMubmEoY291bnRISUdIKSAhPSBUUlVFKSB7ICMgd2UgZXhjbHVkZSBtdC5Db24gYmVjYXVzZSB0aGlzIHBhcmFtZXRlciBhbHdheXMgY29udGFpbnMgYSB2YWx1ZQogICAgaWYgKGZlYXR1cmVMT1cgPj0gMCAmIGZlYXR1cmVMT1cgPD0gbWF4KHNvYmpbWyJuRmVhdHVyZV9STkEiXV0kbkZlYXR1cmVfUk5BKSAmIGlzLm5hKGZlYXR1cmVMT1cpID09IEZBTFNFKSB7CiAgICAgIHNvYmogPC0gc3Vic2V0KHNvYmosIHN1YnNldCA9IG5GZWF0dXJlX1JOQSA+PSBmZWF0dXJlTE9XKQogICAgICB9IGVsc2UgeyB9CiAgICBpZiAoY291bnRMT1cgPj0gMCAmIGNvdW50TE9XIDw9IG1heChzb2JqW1sibkNvdW50X1JOQSJdXSRuQ291bnRfUk5BKSAmIGlzLm5hKGNvdW50TE9XKSA9PSBGQUxTRSkgewogICAgICBzb2JqIDwtIHN1YnNldChzb2JqLCBzdWJzZXQgPSBuQ291bnRfUk5BID49IGNvdW50TE9XKQogICAgICB9IGVsc2UgeyB9CiAgICBpZiAoZmVhdHVyZUhJR0ggPj0gMCAmIGZlYXR1cmVISUdIID49IG1pbihzb2JqW1sibkZlYXR1cmVfUk5BIl1dJG5GZWF0dXJlX1JOQSkgJiBpcy5uYShmZWF0dXJlSElHSCkgPT0gRkFMU0UpIHsKICAgICAgc29iaiA8LSBzdWJzZXQoc29iaiwgc3Vic2V0ID0gbkZlYXR1cmVfUk5BIDw9IGZlYXR1cmVISUdIKQogICAgICB9IGVsc2UgeyB9CiAgICBpZiAoY291bnRISUdIID49IDAgJiBjb3VudEhJR0ggPj0gbWluKHNvYmpbWyJuQ291bnRfUk5BIl1dJG5Db3VudF9STkEpICYgaXMubmEoY291bnRISUdIKSA9PSBGQUxTRSkgewogICAgICBzb2JqIDwtIHN1YnNldChzb2JqLCBzdWJzZXQgPSBuQ291bnRfUk5BIDw9IGNvdW50SElHSCkgCiAgICAgIH0gZWxzZSB7IH0KICAgIGlmIChtdC5Db24gPj0gMCAmIG10LkNvbiA8PSBtYXgoc29ialtbInBlcmNlbnQubXQiXV0kcGVyY2VudC5tdCkgJiBpcy5uYShtdC5Db24pID09IEZBTFNFKSB7CiAgICAgIHNvYmogPC0gc3Vic2V0KHNvYmosIHN1YnNldCA9IHBlcmNlbnQubXQgPD0gaWYgKG10LkNvbiA+PSAwICYgbXQuQ29uIDw9IG1heChzb2JqW1sicGVyY2VudC5tdCJdXSRwZXJjZW50Lm10KSAmIGlzLm5hKG10LkNvbikgPT0gRkFMU0Upe210LkNvbiA9IG10LkNvbn1lbHNle210LkNvbiA9IDEwfSkgCiAgICAgIH0gZWxzZSB7IH0KICB9IGVsc2UgeyAKICAgICMgRWxzZSBpZiB1c2VyIGlucHV0IG5vdCBzcGVjaWZpZWQKICAgIG1pbkNvdj0xMDAwICMgaWYgYSBzYW1wbGUgaGFzIGEgZ29vZCBjb3ZlcmFnZSAoPj1taW5Db3YpLCB0aGVuIGRvbid0IHNldCBhIGxvd2VyIHRocmVzaG9sZCBmb3IgbkNvdW50LCBpdCdzIGFscmVhZHkgcHJldHR5IGdvb2QuIAogICAgaWYgKG1pbihzb2JqJG5Db3VudF9STkEpID49IG1pbkNvdikgeyAgIyBpZiBtaW5pbXVtIFVNSSBjb3VudCBpcyA+PSAxMDAwCiAgICAgIGNvdW50TE9XID0gbWluKHNvYmokbkNvdW50X1JOQSkgICMgdGhlbiwgc2V0IHRvIGxvd2VzdCBuQ291bnQgaWYgd2UgaGF2ZSBnb29kIGNvdmVyYWdlCiAgICAgIH0gZWxzZSB7ICMgT3RoZXJ3aXNlIHVzZSB0aGUgcXVhbnRpbGUgcnVsZQogICAgICAgIGNvdW50TE9XID0gcXVhbnRpbGUoc29iaiRuQ291bnRfUk5BLCBwcm9iPWlmIChVTUkucXVhbnRpbGUubG93ID49IDAgJiBVTUkucXVhbnRpbGUubG93IDw9IDEgJiBpcy5uYShVTUkucXVhbnRpbGUubG93KSA9PSBGQUxTRSl7CiAgICAgICAgICBVTUkucXVhbnRpbGUubG93ID0gVU1JLnF1YW50aWxlLmxvd31lbHNle1VNSS5xdWFudGlsZS5sb3cgPSAwLjAyfSkgCiAgICAgICAgfSAjIGVsc2Ugc2V0IHRvIDIlIHF1YW50aWxlCiAgICBjb3VudEhJR0ggPSBxdWFudGlsZShzb2JqJG5Db3VudF9STkEsIHByb2I9aWYgKFVNSS5xdWFudGlsZS5oaWdoID49IDAgJiBVTUkucXVhbnRpbGUuaGlnaCA8PSAxICYgaXMubmEoVU1JLnF1YW50aWxlLmhpZ2gpID09IEZBTFNFKXsKICAgICAgVU1JLnF1YW50aWxlLmhpZ2ggPSBVTUkucXVhbnRpbGUuaGlnaH1lbHNle1VNSS5xdWFudGlsZS5oaWdoID0gMS4wfSkgIyBTZXQgb24gMS4wIGJlIGRlZmF1bHQsIGJlY2F1c2UgaXQgY24gaW50ZXJmZXJlIHdpdGggRG91YmxldEZpbmRlciwgYnV0IDAuOTggaXMgcmVhc29uYWJsZSBpcyB1c2VyIGxpa2VzIHNwZWNpZnkgdGhhdC4KICAgIGZlYXR1cmVMT1cgPSBxdWFudGlsZShzb2JqJG5GZWF0dXJlX1JOQSwgcHJvYj1pZihmZWF0dXJlLnF1YW50aWxlLmxvdyA+PSAwICYgZmVhdHVyZS5xdWFudGlsZS5sb3cgPD0gMSAmIGlzLm5hKGZlYXR1cmUucXVhbnRpbGUubG93KSA9PSBGQUxTRSl7CiAgICAgIGZlYXR1cmUucXVhbnRpbGUubG93ID0gZmVhdHVyZS5xdWFudGlsZS5sb3d9ZWxzZXtmZWF0dXJlLnF1YW50aWxlLmxvdyA9IDAuMDJ9KSAKICAgIGZlYXR1cmVISUdIID0gcXVhbnRpbGUoc29iaiRuRmVhdHVyZV9STkEsIHByb2I9aWYgKGZlYXR1cmUucXVhbnRpbGUuaGlnaCA+PSAwICYgZmVhdHVyZS5xdWFudGlsZS5oaWdoIDw9IDEgJiBpcy5uYShmZWF0dXJlLnF1YW50aWxlLmhpZ2gpID09IEZBTFNFKXsKICAgICAgZmVhdHVyZS5xdWFudGlsZS5oaWdoID0gZmVhdHVyZS5xdWFudGlsZS5oaWdofWVsc2V7ZmVhdHVyZS5xdWFudGlsZS5oaWdoID0gMS4wfSkgCiAgICAjIGZpbHRlciBiYXNlZCBvbiBvbiB2aXN1YWxpemF0aW9uIGFuIHBhcmFtZXRlcnMgYWJvdmUuCiAgICBzb2JqIDwtIHN1YnNldChzb2JqLCBzdWJzZXQgPSBuRmVhdHVyZV9STkEgPj0gZmVhdHVyZUxPVyAmIG5GZWF0dXJlX1JOQSA8PSBmZWF0dXJlSElHSCAmIG5Db3VudF9STkEgPj0gY291bnRMT1cgJiBuQ291bnRfUk5BIDw9IGNvdW50SElHSCAmIHBlcmNlbnQubXQgPD0gaWYgKG10LkNvbiA+PSAwICYgbXQuQ29uIDw9IG1heChzb2JqW1sicGVyY2VudC5tdCJdXSRwZXJjZW50Lm10KSAmIGlzLm5hKG10LkNvbikgPT0gRkFMU0Upe210LkNvbiA9IG10LkNvbn1lbHNle210LkNvbiA9IDEwfSkKICAgICMgc29iaiA8LSBzdWJzZXQoc29iaiwgc3Vic2V0ID0gbkZlYXR1cmVfUk5BID4gZmVhdHVyZUxPVyAmIG5Db3VudF9STkEgPiBjb3VudExPVyAmIG5Db3VudF9STkEgPCBjb3VudEhJR0ggJiBuRmVhdHVyZV9STkEgPCBmZWF0dXJlSElHSCAmIHBlcmNlbnQubXQgPCAxMCkgIyBVU0UgVEhJUyBMSU5FIElGIElOQ0xVRElORyBmZWF0dXJlSElHSCBhbmQgY291bnRMT1cgcGFyYW1ldGVycwogIAogICAgIyBBZnRlciBpbml0aWFsIGZpbHRlcmluZywgd2UgY291bGQgc2F2ZSBvbmUgYmFja3VwIGluIG9yZGVyIHRvIGFwcGx5IGFtYmllbnQgYW5kIG11bHRpcGxldCByZW1vdmFsIG9uIHRoaXMgb2JqZWN0CiAgICAjIHNvYmouZmlsdGVyZWQgPC0gc3Vic2V0KHNvYmosIHN1YnNldCA9IG5GZWF0dXJlX1JOQSA+IGZlYXR1cmVMT1cgJiBuQ291bnRfUk5BID4gY291bnRMT1cgICYgbkNvdW50X1JOQSA8IGNvdW50SElHSCAmIHBlcmNlbnQubXQgPCAxMCkKICB9CiAgcmV0dXJuKHNvYmopCiAgfQogIAojIEFwcGx5IGZ1bmN0aW9uIGFuZCBwcmludCB0aGUgb3V0cHV0IGZvciBjb250cm9sCnNvYmpfbGlzdCA8LSBzYXBwbHkoc29ial9saXN0LCBleHRfZmlsdGVyaW5nKQpmb3IgKGkgaW4gMTpsZW5ndGgoeCA9IHNvYmpfbGlzdCkpIHsKICBwcmludChzb2JqX2xpc3RbaV0pCn0KCgoKCiMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIFRFU1RJTkcgQ09ERSBQSVBFICMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIwoKI2lmIChmZWF0dXJlTE9XID4gMCAmIGlzLm5hKGZlYXR1cmVMT1cpID09IEZBTFNFKSB7CiMgIHNvYmogPC0gc3Vic2V0KHNvYmosIHN1YnNldCA9IG5GZWF0dXJlX1JOQSA+IGZlYXR1cmVMT1cpCiN9IGVsc2UgeyB9CiNpZiAoY291bnRMT1cgPiAwICYgaXMubmEoY291bnRMT1cpID09IEZBTFNFKSB7CiMgIHNvYmogPC0gc3Vic2V0KHNvYmosIHN1YnNldCA9IG5Db3VudF9STkEgPiBjb3VudExPVykKI30gZWxzZSB7IH0KI2lmIChmZWF0dXJlSElHSCA+IDAgJiBpcy5uYShmZWF0dXJlSElHSCkgPT0gRkFMU0UpIHsKIyAgc29iaiA8LSBzdWJzZXQoc29iaiwgc3Vic2V0ID0gbkZlYXR1cmVfUk5BIDwgZmVhdHVyZUhJR0gpCiN9IGVsc2UgeyB9CiNpZiAoY291bnRISUdIID4gMCAmIGlzLm5hKGNvdW50SElHSCkgPT0gRkFMU0UpIHsKIyAgc29iaiA8LSBzdWJzZXQoc29iaiwgc3Vic2V0ID0gbkNvdW50X1JOQSA8IGNvdW50SElHSCkgCiN9IGVsc2UgeyB9CiNpZiAocGVyY2VudC5tdCA+IDAgJiBpcy5uYShwZXJjZW50Lm10KSA9PSBGQUxTRSkgewojICBzb2JqIDwtIHN1YnNldChzb2JqLCBzdWJzZXQgPSBwZXJjZW50Lm10IDwgbXQuQ29uKSAKI30gZWxzZSB7IH0KCiNybShzb2JqMSkKCiNxdWFudGlsZShzb2JqX2xpc3RbWzFdXSRuRmVhdHVyZV9STkEsIHByb2I9MC4wMikgCiNxdWFudGlsZShzb2JqX2xpc3RbWzFdXSRuQ291bnRfUk5BLCBwcm9iPTAuMDIpCgojbWF4KHNvYmpfbGlzdFtbaV1dW1sicGVyY2VudC5tdCJdXSRwZXJjZW50Lm10KQojbWF4KHNvYmpfbGlzdFtbaV1dW1sibkNvdW50X1JOQSJdXSRuQ291bnRfUk5BKSAKI21heChzb2JqX2xpc3RbW2ldXVtbIm5GZWF0dXJlX1JOQSJdXSRuRmVhdHVyZV9STkEpCiNtaW4oc29ial9saXN0W1tpXV1bWyJuQ291bnRfUk5BIl1dJG5Db3VudF9STkEpIAojbWluKHNvYmpfbGlzdFtbaV1dW1sibkZlYXR1cmVfUk5BIl1dJG5GZWF0dXJlX1JOQSkKCiMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIFRFU1RJTkcgQ09ERSBGT1IgU0lOR0xFVFMgIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCiNtaW5Db3Y9MTAwMCAjaWYgYSBzYW1wbGUgaGFzIGEgZ29vZCBjb3ZlcmFnZSAoPj1taW5Db3YpLCB0aGVuIGRvbid0IHNldCBhIGxvd2VyIHRocmVzb2xkIGZvciBuQ291bnQsIGl0J3MgYWxyZWFkeSBwcmV0dHkgZ29vZC4gCiNpZiAobWluKHNvYmokbkNvdW50X1JOQSkgPj0gbWluQ292KSAgIyBpZiBtaW5pbXVtIFVNSSBjb3VudCBpcyA+PSAxMDAwCiMgICAgeyBjb3VudExPVyA9IG1pbihzb2JqJG5Db3VudF9STkEpICAjIHRoZW4sIHNldCB0byBsb3dlc3QgbkNvdW50IGlmIHdlIGhhdmUgZ29vZCBjb3ZlcmFnZQojICB9IGVsc2UgeyBjb3VudExPVz1xdWFudGlsZShzb2JqJG5Db3VudF9STkEsIHByb2I9YygwLjAyKSkgfSAjIGVsc2Ugc2V0IHRvIDIlIHF1YW50aWxlCiNjb3VudEhJR0ggPSBxdWFudGlsZShzb2JqJG5Db3VudF9STkEsIHByb2I9MC45OSkgIyBhbmQgdG8gOTklIHF1YW50aWxlIGZvciB0aGUgdXBwZXIgY291bnQsIGJlY2F1c2UgdGhlc2UgaGlnaCBVTUktY291bnQgY2VsbHMgd2lsbCBhbHNvIGJlIGZpbHRlcmVkIG91dCBieSB0aGUgRG91YmxldEZpbmRlciBvciByZWR1Y2VkIHdoZW4gYWRqdXN0aW5nIGZvciBhbWJpZW50IFJOQSBjb3VudHMKI2ZlYXR1cmVMT1cgPSBxdWFudGlsZShzb2JqJG5GZWF0dXJlX1JOQSwgcHJvYj0wLjAyKSAgIyBtaW5pbXVtIG51bWJlciBvZiBnZW5lcyBzZXQgdG8gMiUgcXVhbnRpbGUKI2ZlYXR1cmVISUdIID0gcXVhbnRpbGUoc29iaiRuRmVhdHVyZV9STkEsIHByb2I9MC45OSkKIyBmaWx0ZXIgYmFzZWQgb24gb24gdmlzdWFsaXphdGlvbiBhbiBwYXJhbWV0ZXJzIGFib3ZlLgojc29iaiA8LSBzdWJzZXQoc29iaiwgc3Vic2V0ID0gbkZlYXR1cmVfUk5BID4gZmVhdHVyZUxPVyAmIG5Db3VudF9STkEgPiBjb3VudExPVyAgJiBuQ291bnRfUk5BIDwgY291bnRISUdIICYgcGVyY2VudC5tdCA8IDEwKQojc29iagoKIyBBZnRlciBpbml0aWFsIGZpbHRlcmluZywgd2Ugd2lsbCBzYXZlIG9uZSBiYWNrdXAgaW4gb3JkZXIgdG8gYXBwbHkgYW1iaWVudCBhbmQgbXVsdGlwbGV0IHJlbW92YWwgb24gdGhpcyBvYmplY3QKI3NvYmouZmlsdGVyZWQgPC0gc3Vic2V0KHNvYmosIHN1YnNldCA9IG5GZWF0dXJlX1JOQSA+IGZlYXR1cmVMT1cgJiBuQ291bnRfUk5BID4gY291bnRMT1cgICYgbkNvdW50X1JOQSA8IGNvdW50SElHSCAmIHBlcmNlbnQubXQgPCAxMCkKYGBgCgojIyMjIE11bHRpcGxldCBSZW1vdmFsICMjIyMKCiMjIyMjIERlc2NyaXB0aW9uOiAjIyMjIwoKKiBUaGUgRG91YmxldEZpbmRlciBhbGdvcml0aG0gZmlyc3QgZ2VuZXJhdGVzIGFydGlmaWNpYWwgZG91YmxldHMgYnkgcmFuZG9tbHkgbWVyZ2luZyBkaWZmZXJlbnQgY2VsbHMgZnJvbSB0aGUgZGF0YS4gSW4gdG90YWwsIG9uZSBhcnRpZmljaWFsIGRvdWJsZXQgaXMgZ2VuZXJhdGVkIHBlciBmb3VyIGNlbGxzLiBXZSBhcmUgZXNzZW50aWFsbHkgY3JlYXRpbmcgYSBuZXcgZGF0YXNldCB3aGVyZSBhcnRpZmljaWFsIGRvdWJsZXRzIGFyZSBhZGRlZCB0byB0aGUgbWl4LiBCeSBkb2luZyBzbywgdGhlIGFydGlmaWNpYWwgZG91YmxldHMgcmVzZW1ibGUgZHJvcGxldHMgdGhhdCBtYXkgY29udGFpbiB0d28gY29tcGxldGVseSBkaWZmZXJlbnQgY2VsbCB0eXBlcy4gQXJndWFibHksIHRoZSBzYW1lIHByb2Nlc3MgbGlrZWx5IG9jY3VycyBhcyB0cnVlIGRvdWJsZXRzIGZvcm0gaW4gdGhlIG1pY3JvZmx1aWRpYyBjb250YWluZXIuIERvdWJsZXRGaW5kZXIgdGhlbiBjYXJyaWVzIG91dCBQQ0FzIHVzaW5nIG91ciBwcmV2aW91c2x5IGRldGVybWluZWQgb3B0aW1hbCBudW1iZXIgb2YgUEMtZGltZW5zaW9ucyAoZHVyaW5nIHRoZSB1bnN1cGVydmlzZWQgY2x1c3RlcmluZyBzdGVwKS4gVGhlIFBDIGRpc3RhbmNlIG1hdHJpeCBpcyB0aGVuIHVzZWQgdG8gZmluZCBhcnRpZmljaWFsIEstbmVhcmVzdCBuZWlnaGJvcnMgdG8gZGVmaW5lIHdoZXJlIHRoZSB0cnVlIGFuZCB0aGUgYXJ0aWZpY2lhbCBkb3VibGV0cyBzaGFyZSB0aGUgc2FtZSBuZWlnaGJvcmhvb2QuIFRoaXMgc3RlcCBpcyByZWN1cnNpdmUgYW5kIGNvbXB1dGF0aW9uYWwgZXhwZW5zaXZlIGFuZCB0aHVzIHdlIGFsbG93IHRoZSB1c2VyIHRvIGNob29zZSB0aGUgbnVtYmVyIG9mIENQVS1jb3JlcyAoNCBjb3JlcyBieSBkZWZhdWx0KS4gT25jZSBjb21wbGV0ZSwgd2UgcmVtb3ZlIHRoZSBhZGRlZCBhcnRpZmljaWFsIGRvdWJsZXRzIGFuZCB0aGUgcHJlLWRlZmluZWQgcHJvcG9ydGlvbiBvZiBpZGVudGlmaWVkIHJlYWwgZG91YmxldHMgZnJvbSB0aGUgZGF0YXNldC4KCiogU2luY2UgdGhlcmUgaXMgYSBsaW5lYXIgcmVsYXRpb25zaGlwIGJldHdlZW4gdGhlIHBlcmNlbnRhZ2Ugb2YgdHJ1ZSBkb3VibGV0cyBhbmQgbnVtYmVyIG9mIHJlY292ZXJlZCBjZWxscyBmb3IgdGhlICJTaW5nbGUgQ2VsbCAzJyBHZW5lIEV4cHJlc3Npb24gQXNzYXkiLCB3ZSBpbXBsZW1lbnRlZCB0aGlzIGxpbmVhcml0eSBpbiB0aGUgYWxnb3JpdGhtIHRvIGVuc3VyZSB0aGUgbW9kZWwgZG9lcyBub3Qgb3ZlciBvciB1bmRlcmVzdGltYXRlIHRoZSB0cnVlIGRvdWJsZXRzIGluIHRoZSBkYXRhc2V0LiAKCiogVGhlIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIHRoZSBudW1iZXIgb2YgcmVjb3ZlcmVkIGNlbGxzIGFuZCB0cnVlIGRvdWJsZXRzIGlzIHByb3ZpZGVkIGJ5IDEwWCAoaHR0cHM6Ly9rYi4xMHhnZW5vbWljcy5jb20vaGMvZW4tdXMvYXJ0aWNsZXMvMzYwMDAxMzc4ODExLVdoYXQtaXMtdGhlLW1heGltdW0tbnVtYmVyLW9mLWNlbGxzLXRoYXQtY2FuLWJlLXByb2ZpbGVkLSkuIFdlIG1ha2UgYSBsaW5lYXIgcmVncmVzc2lvbiBmcm9tIHRoaXMgYW5kIGltcGxlbWVudCBpdCBpbnRvIERvdWJsZXRGaW5kZXIuCgoqIFBsZWFzZSBpbmNyZWFzZSB0aGUgbnVtYmVyIG9mIGNvcmVzIGZvciB0aGlzIHN0ZXAgaWYgaGF2ZSBtYW55IGNlbGxzLiBGaW5kaW5nIGFydGlmaWNpYWwgSy1uZWFyZXN0IG5laWdoYm9ycyBkdXJpbmcgdGhlIHBhcmFtZXRlciBzd2VlcCBjYW4gYmUgY29tcHV0YXRpb25hbGx5IGV4cGVuc2l2ZS4gVGhlIG51bWJlciBvZiBjb3JlcyBzaG91bGQgTk9UIGV4Y2VlZCB0aGUgYXZhaWxhYmxlIHJlc291cmNlcyBpbiB5b3VyIHN5c3RlbSBwcm92aWRlZCB0byB0aGUgcGlwZWxpbmUuIElmIHlvdSBkbywgdGhlbiBEb3VibGV0RmluZGVyIHdpbGwgbGlrZWx5IGNyYXNoIQoKIyMjIyMgUmVzdWx0czogIyMjIyMKCiogRG91YmxldCBVTUFQIHBsb3Q6IAogIC0gUmVwcmVzZW50aW5nIHRoZSBpZGVudGlmaWVkIGRvdWJsZXRzIHdpdGhpbiB0aGUgcHJlbGltaW5hcnkgY2x1c3Rlci4gT2Z0ZW4sIHRoZSBkb3VibGV0cyBhcmUgbG9jYXRlZCBvbiB0aGUgZWRnZXMgb3IgYmV0d2VlbiBvdGhlciBjZWxsIHBvcHVsYXRpb24uCiAgCiogVmlvbGluIHBsb3RzOgogIC0gUmVwcmVzZW50aW5nIHRoZSBzY2F0dGVyZWQgZGlzdHJpYnV0aW9uIG9mIGRvdWJsZXRzIGFuZCBzaW5nbGV0cyBhcyBhIGZ1bmN0aW9uIG9mIGdlbmUgYW5kIHRyYW5zY3JpcHQgY291bnRzLiBIZXJlIGl0IGlzIGV4cGVjdGVkIHRoYXQgdGhlIGRvdWJsZXRzIGNvbnRhaW4gbW9yZSBnZW5lcyBhbmQgdHJhbnNjcmlwdHMgd2hlbiBjb21wYXJlZCB0byBzaW5nbGV0cy4KYGBge3IgRG91YmxldGZpbmRlciAtIEZpbmRpbmcgdGhlIG9wdGltYWwgUGsgdmFsdWUgZm9yIGRvdWJsZXRmaW5kZXIsIGZpZy5oZWlnaHQ9NCwgZmlnLndpZHRoPTEwLCBlY2hvPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCByZXN1bHRzPSdoaWRlJywgIGluY2x1ZGU9RkFMU0V9CiMjIyMjIyMjIyMjIyMjIyMjIyMjIENodW5rICMjIyMjIyMjIyMjIyMjIyMjIyMjIAojIC8vIFRoaXMgY2h1bmsgcmVjdXJzaXZlbHkgZGV0ZXJtaW5lcyB0aGUgb3B0aW1hbCBudW1iZXIgb2YgcEsgdmFsdWUgZm9yIHRoZSBwcm9iYWJpbGlzdGljIGRldGVybWluYXRpb24gb2YgbXVsdGlwbGV0cwojIC8vIHBLIGRlZmluZXMgdGhlIFBDIG5laWdoYm9yaG9vZCBzaXplIHVzZWQgdG8gY29tcHV0ZSB0aGUgcHJvcG9ydGlvbiBvZiBhcnRpZmljaWFsIGsgbmVhcmVzdCBuZWlnaGJvcnMgZm9yIGVhY2ggY2VsbCwgZXhwcmVzc2VkIGFzIGEgcHJvcG9ydGlvbiBvZiB0aGUgbWVyZ2VkIHJlYWwtYXJ0aWZpY2lhbCBkYXRhLgojIC8vIE9wdGltYWwgcEsgdmFsdWVzIGFyZSBhbHdheXMgYmV0d2VlbiAwIGFuZCAwLjMgKDAtMzAlKSBieSBkZWZhdWx0CiMgLy8gcE4gZGVmaW5lcyB0aGUgbnVtYmVyIG9mIGdlbmVyYXRlZCBhcnRpZmljaWFsIGRvdWJsZXRzLCBleHByZXNzZWQgYXMgYSBwcm9wb3J0aW9uIG9mIHRoZSBtZXJnZWQgcmVhbC1hcnRpZmljaWFsIGRhdGEuIERlZmF1bHQgaXMgc2V0IHRvIDI1JSAoaW1wbGVtZW50IHVzZXIgcGFyYW1ldGVyKQojIyMjIyMjIyMjIyMjIyMjIyMjIyAgICAgICAjIyMjIyMjIyMjIyMjIyMjIyMjIyAKCiMgTGV0cyBjYWxjdWxhdGUgdGhlIG9wdGltYWwgUGsgdmFsdWUgZm9yIGRvdWJsZXRmaW5kZXIKZm9yIChpIGluIDE6bGVuZ3RoKHggPSBzYW1wbGVfbmFtZXMpKSB7CiAgc3dlZXAucmVzLmxpc3Rfc29iaiA8LSBwYXJhbVN3ZWVwKHNvYmpfbGlzdFtbaV1dLCBQQ3MgPSBwYy5kaW1zW1tpXV0sIHNjdCA9IEZBTFNFLCBudW0uY29yZXMgPSBpZiAoQ1BVLmNvcmVzID49IDAgJiBDUFUuY29yZXMgPD0gOCAmIGlzLm5hKENQVS5jb3JlcykgPT0gRkFMU0UpewogICAgQ1BVLmNvcmVzID0gQ1BVLmNvcmVzfWVsc2V7Q1BVLmNvcmVzID0gMX0pICMgc2V0IENQVSBjb3JlcyAxIGJ5IGRlZmF1bHQsIGJ1dCBubyBoaWdoZXIgdGhhbiA4IGlmIHVkZXIgZGVmaW5lZAogIHN3ZWVwLnN0YXRzX3NvYmogPC0gc3VtbWFyaXplU3dlZXAoc3dlZXAucmVzLmxpc3Rfc29iaiwgR1QgPSBGQUxTRSkKICBiY212bl9zb2JqIDwtIGZpbmQucEsoc3dlZXAuc3RhdHNfc29iaikKCiAgIyBzZWxlY3QgdGhlIHBLIHRoYXQgY29ycmVzcG9uZHMgdG8gbWF4IGJjbXZuIHRvIG9wdGltaXplIGRvdWJsZXQgZGV0ZWN0aW9uCiAgcEsgPC0gYmNtdm5fc29iaiAlPiUgCiAgICBkcGx5cjo6ZmlsdGVyKEJDbWV0cmljID09IG1heChCQ21ldHJpYykpICU+JSAKICAgIGRwbHlyOjpzZWxlY3QocEspIAogIAogIHBLIDwtIGFzLm51bWVyaWMoYXMuY2hhcmFjdGVyKHBLW1sxXV0pKSAjIG1ha2UgaW50ZWdlcgogIAogICMgbGV0cyBwbG90IHRvIHNvbyB0aGUgb3B0aW1hbCBQSyB2YWx1ZQogIHBsb3R0dHQgPC0gZ2dwbG90KGJjbXZuX3NvYmosIGFlcyhwSywgQkNtZXRyaWMsIGdyb3VwID0gMSkpICsgZ2VvbV9wb2ludCgpICsgZ2VvbV9saW5lKCkKICBwcmludChwbG90dHR0KQogIAogICMgRXN0aW1hdGUgdGhlIHByb3BvcnRpb24gb2YgZG91YmxldHMgaW4gb3VyIGRhdGEgYW5kIHJ1biBEb3VibGV0RmluZGVyCiAgY2x1c3RlcnMgPC0gc29ial9saXN0W1tpXV1AbWV0YS5kYXRhJHNldXJhdF9jbHVzdGVyICMgcHJldmlvdXMgY2x1c3RlciBmcm9tIFVNQVAKICBkb3VibGV0LnByb3BvdGlvbnMgPC0gbW9kZWxIb21vdHlwaWMoY2x1c3RlcnMpIAogIG5FeHBfcG9pIDwtIHJvdW5kKHBlcmNlbnQubXVsdGlwbGV0c1tbaV1dKm5yb3coc29ial9saXN0W1tpXV1AbWV0YS5kYXRhKSkgICMjIEFzc3VtaW5nIDQuOCUgZG91YmxldCBmb3JtYXRpb24gcmF0ZSAKICBuRXhwX3BvaS5hZGogPC0gcm91bmQobkV4cF9wb2kqKDEtZG91YmxldC5wcm9wb3Rpb25zKSkKICAjIFJ1biBkb3VibGV0ZmluZGVyCiAgCiAgc29ial9saXN0W1tpXV0gPC0gZG91YmxldEZpbmRlcihzb2JqX2xpc3RbW2ldXSwgUENzID0gcGMuZGltc1tbaV1dLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBOID0gMC4yNSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBLID0gcEssIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbkV4cCA9IG5FeHBfcG9pLmFkaiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXVzZS5wQU5OID0gRkFMU0UsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2N0ID0gRkFMU0UpCn0KYGBgCgpgYGB7ciB2aXN1YWxpemUgdGhlIG51bWJlciBvZiBkb3VibGV0cyBpbiBjbHVzdGVyLCBmaWcuaGVpZ2h0PTUsIGZpZy53aWR0aD02LCBlY2hvPUZBTFNFfQojIyMjIyMjIyMjIyMjIyMjIyMjIyBDaHVuayAjIyMjIyMjIyMjIyMjIyMjIyMjIyAKIyAvLyBUaGlzIGNodW5rIHZpc3VhbGl6ZWQgdGhlIHRydWUgaWRlbnRpZmllZCBtdWx0aXBsZXRzIGluIHZpb2xpbiBwbG90IGFuZCBVTUFQIHNwYWNlCiMjIyMjIyMjIyMjIyMjIyMjIyMjICAgICAgICMjIyMjIyMjIyMjIyMjIyMjIyMjIAoKIyMjIyMjIyMjIyBGdW5jdGlvbiAjIyMjIyMjIyMjIAojIC8vIFRoaXMgZnVuY3Rpb24gcmV0dXJuIGEgdmlvbGluIGFuZCBVTUFQIHBsb3Qgb2YgdGhlIGlkZW50aWZpZWQgbXVsdGlwbGV0cyBieSBEb3VibGV0RmluZGVyCiMgLy8gSW5wdXQgZmlsZSBtdXN0IGJlIGEgdmVjdG9yIG9mIFNldXJhdCBvYmplY3RzIHRoYXQgaGF2ZSBiZWVuIHVzZWQgaW5wdXQgZm9yIERvdWJsZXRGaW5kZXIKc2hvd19kb3VibGV0cyA8LSBmdW5jdGlvbihzb2JqKSB7CiAgY29sbmFtZXMoc29iakBtZXRhLmRhdGEpW2xlbmd0aChzb2JqQG1ldGEuZGF0YSldIDwtIGFzLmNoYXJhY3Rlcihzb2JqQG1ldGEuZGF0YVsxLDFdKSAjIGNoYW5nZSBjb2x1bW4gbmFtZSBvZiBtdWx0aXBsZXQgY2hhbm5lbCB0byBzYW1wbGUgbmFtZQogIG11bHRpcGxldC5jaGFubmVsIDwtIGNvbG5hbWVzKHNvYmpAbWV0YS5kYXRhKVtsZW5ndGgoc29iakBtZXRhLmRhdGEpXSAjIGNvbHVtbiA4IG9mIHRoZSBzZXVyYXQgb2JqZWN0QG1ldGFkYXRhIGNvcmVzcG9uZHMgdG8gdGhlIGRvdWJsZXQgY2hhbm5lbAogIAogICMgVU1BUCBwbG90IHRoZSBkb3VibGV0cyBhbmQgc2luZ2xldHMgdXNpbmcgdGhlIG9yaWdpbmFsIGxvdmFpbiBVTUFQIHBsb3QKICBkb3VibGV0X3Bsb3QgPC0gRGltUGxvdChzb2JqLCByZWR1Y3Rpb24gPSAndW1hcCcsIGdyb3VwLmJ5ID0gbXVsdGlwbGV0LmNoYW5uZWwsIHB0LnNpemUgPSAwLjA1KSArIAogICAgZ2d0aXRsZShwYXN0ZSgiTXVsdGlwbGV0IERldGVjdGlvbjogVU1BUDoiLCBzb2JqQG1ldGEuZGF0YVsxLDFdLCBzZXAgPSAiICIpLCAKICAgICAgICAgICAgc3VidGl0bGUgPSBwYXN0ZSh0YWJsZShzb2JqQG1ldGEuZGF0YVtsZW5ndGgoc29iakBtZXRhLmRhdGEpXSlbMV0sIHBhc3RlKHRhYmxlKHNvYmpAbWV0YS5kYXRhW2xlbmd0aChzb2JqQG1ldGEuZGF0YSldKVsyXSwgIk11bHRpcGxldHMiKSwgc2VwID0gIi8iKSkgKyAKICAgIHlsYWIoIlVNQVAgMSIpICsgeGxhYigiVU1BUCAyIikgKyB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCkpCiAgcHJpbnQoZG91YmxldF9wbG90KQogIAogICMgcGxvdCB2aW9saW4gb2YgbnVtYmVyIG9mIGdlbmVzL1VNSXMgZm9yIGRvdWJsZXRzIGFuZCBzaW5nbGV0cwogIHYxLjEgPC0gVmxuUGxvdChzb2JqLCBmZWF0dXJlcyA9ICJuRmVhdHVyZV9STkEiLCBncm91cC5ieSA9IG11bHRpcGxldC5jaGFubmVsLCBwdC5zaXplID0gMC4xKSArIAogICAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTApKQogIHYxLjIgPC0gVmxuUGxvdChzb2JqLCBmZWF0dXJlcyA9ICJuQ291bnRfUk5BIiwgZ3JvdXAuYnkgPSBtdWx0aXBsZXQuY2hhbm5lbCwgcHQuc2l6ZSA9IDAuMSkgKyAKICAgIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwKSkKICBwcmludCh2MS4xKQogIHByaW50KHYxLjIpCiAgCiAgIyBzaG93IHRoZSBudW1iZXIgb2YgYWN0dWFsIGRvdWJsZXRzIGluIHRoZSBkYXRhCiAgcHJpbnQodGFibGUoc29iakBtZXRhLmRhdGFbbGVuZ3RoKHNvYmpAbWV0YS5kYXRhKV0pKQogIAogIHJldHVybigpCn0KIyBFeGVjdXRlIHNob3dfZG91YmxldHMgZnVuY3Rpb24KZG91YmxldF9yZXN1bHQgPC0gc2FwcGx5KHNvYmpfbGlzdCwgc2hvd19kb3VibGV0cykKYGBgCgojIyMjIEZpbmFsIGZpbHRlcmluZyBhbmQgUUMgcGxvdHMgIyMjIwoKIyMjIyMgUmVzdWx0czogIyMjIyMKCiogSW4gdGhlIGNodWNrIGJlbG93LCB3ZSB3aWxsIGRvIGFub3RoZXIgZGF0YSBmaWx0ZXJpbmcgYnkgdGFraW5nIG91dCB0aGUgaWRlbnRpZmllZCBtdXVsdGlwbGV0cyBpbiB0aGUgZGF0YXNldC4KICAtIE5vdyB5b3UgaGF2ZSBjYW4gZmluYWxseSBjb21wYXJlIHlvdXIgcmVzdWx0cyBhbmQgbnVtYmVyIG9mIGNlbGxzIGJlZm9yZSBhbmQgYWZ0ZXIgZmlsdGVyaW5nLiBJdCBnaXZlcyB5b3UgYW4gaWRlYSBob3cgYWdncmVzc2l2ZWx5IHlvdSBoYXZlIGZpbHRlcmVkIHlvdXIgZGF0YS4gCiAgLSBMaWtld2lzZSwgeW91IGNhbiBjb21wYXJlIHRoZSBRQyBwbG90cyB0byB3aGF0IGhhZCBiZWZvcmUuIERvIHlvdSBzZWUgYW55IGltcHJvdmVtZW50IGhlcmU/IAogIC0gUmVtZW1iZXIgdGhhdCB5b3UgY2FuIGFsd2F5cyBjaGFuZ2UgdGhlIHBhcmFtZXRlcnMgdG8geW91ciBsaWtpbmcgYW4gcnVuIGl0IGFnYWluLgogIAoqIEl0IGlzIGFkdmlzZWQgdG8gdHJ5IHRvIGFubm90YXRlIHlvdSBjZWxscyB1c2luZyB0aGUgcHJlLXByb2Nlc3NlZCBkYXRhIGFuZCBzZWUgaWYgeW91IGZpbmQgeW91ciBleHBlY3RlZCBjZWxscyAoaW4gdGhlIHJpZ2h0IHByb3BvcnRpb24pLiBJZiB5b3UgdGhpbmsgdGhhdCB5b3UgYXJlIG1pc3Npbmcgc29tZSByYXJlIGNlbGxzIHRoYXQgY29udGFpbiBmZXcgZ2VuZXMvdHJhbnNjcmlwdHMsIHRoZW4gdHJ5IHRvIHVzZSB0aGUgcmF3IGNvdW50cyBtYXRyaXggYXMgYSBzdGFydGluZyBwb2ludC4gVGhpcyB3aWxsIGxpa2VseSBleHBvc2UgdGhvc2UgY2VsbHMgdGhhdCBoYXZlIGJlZW4gZmlsdGVyZWQgb3V0IGJ5IENlbGxyYW5nZXJzIDUwMCBVTUkgdGhyZXNob2xkLiBCeSB1c2luZyB0aGUgcmF3IG1hdHJpeCwgdGhlIHBpcGVsaW5lIHdpbGwgYXV0b21hdGljYWxseSByZW1vdmUgYWxsIGNlbGxzIHRoYXQgaGF2ZSA8MTAwIGdlbmVzLiBCeSBkb2luZyBzbywgd2UgZW5zdXJlIHRoYXQgeW91IGRvIG5vdCBlbmQgdXAgbWFueSBsb3cgcXVhbGl0eSBkcm9wbGV0cy4gRXZlbiB0aGUgcmFyZXN0IGNlbGxzIHVzdWFsbHkgZG8gbm90IGNvbnRhaW4gbGVzcyB0aGFuIDEwMCBnZW5lcyBhbnl3YXkuIEZlZWwgZnJlZSB0byBkaXNhZ3JlZSBhbmQgY2hhbmdlIHRoZSBwYXJhbWV0ZXIgdG8geW91ciBsaWtpbmcuIElmIHlvdSBkbyBub3QgY2hhbmdlIGFueXRoaW5nLCB0aGVuIHRoZSB0aHJlc2hvbGQgaXMgYWx3YXlzIHNldCBhdCAxMDAgZ2VuZXMuIE5FVkVSIFRPVUNIIFRISVMgUEFSQU1FVEVSIElGIFlPVSBBRUUgV09SS0lORyBXSVRIIFRIRSBGSUxURVJFRCBDT1VOVFMgTUFUUklYISBZb3Ugd2lsbCBhbHdheXMgbG9zZSBjZWxscyB0aGF0IGNvbnRhaW4gZmV3IGdlbmVzL3RyYW5zY3JpcHRzLiAKYGBge3IgZmlsdGVyIGFuZCByZW1vdmUgZG91YmxldHMgaW4gdGhlIGRhdGEsIGZpZy5oZWlnaHQ9OSwgZmlnLndpZHRoPTE3LCBlY2hvPUZBTFNFfSAKIyMjIyMjIyMjIyMjIyMjIyMjIyMgQ2h1bmsgIyMjIyMjIyMjIyMjIyMjIyMjIyMgCiMgLy8gVGhpcyBjaHVuayBzYXZlcyB0aGUgZmluYWwgb3V0cHV0IGNvdW50IG1hdHJpeCB0aGF0IGhhcyBiZWVuIGZ1bGx5IHByb2Nlc3NlZCAoZmlsdGVyZWQpLCBjb3JyZWN0ZWQgZm9yIGFtYmllbnQgUk5BIGFuZCByZW1vdmVkIG11bHRpcGxldHMKIyAvLyBBZGRpdGlvbmFsbHksIHRoZSBmdWxseSBwcm9jZXNzZWQgb2JqZWN0IHdpbGwgYmUgdXNlZCB0aGUgcGxvdCBhbGwgdGhlIHByZXZpb3VzIFFDIHBsb3RzIHBsb3RzIHdoZXJlIHRoZSB1c2VyIGNhbiB2aXN1YWxseSBjb21wYXJlIHRoZSBwcmUgdnMgcG9zdCBmaWx0ZXJpbmcKIyMjIyMjIyMjIyMjIyMjIyMjIyMgICAgICAgIyMjIyMjIyMjIyMjIyMjIyMjIyMgCgpmb3IgKGkgaW4gMTpsZW5ndGgoeCA9IHNvYmpfbGlzdCkpIHsKICBpZiAoc2tpcC5Eb3VibGV0RmluZGVyID09ICJ5ZXMiICYgc3RyX2xlbmd0aChza2lwLkRvdWJsZXRGaW5kZXIpICE9IDApIHsgIyBJZiB3ZSBoYXZlIGxvdyBjb21wbGV4aXR5IGRhdGEgb3Igd3JvbmcgcGFyYW1ldGVyIGdpdmVuLCB0aGVuIFNvdXBYIHdpbGwgYmUgc2tpcHBlZAogICAgcHJpbnQoIkNvcnJlY3Rpb24gZm9yIG11bHRpcGxldHMgd2lsbCBub3QgYmUgY2FycmllZCBvdXQiKQogICAgIyBJZiB0aGVyZSBpcyBhIGRpcmVjdG9yeSwgdGhlbiBtYWtlIG5ldyBvbmUgYW5kIHNhdmUgU2VtaSBmaWx0ZXJlZCBtYXRyaXggCiAgICBpZiAoZGlyLmV4aXN0cyhmaWxlLnBhdGgocGFzdGUocGFyZW50X2RpcmVjdG9yeSwgcGFzdGUoc2FtcGxlX3BhdGhbaV0sICIvbmV3LW91dHMvY291bnRzIiwgc2VwID0gIiIpLCBzZXAgPSAiLyIpKSkpIHsKICAgICAgd3JpdGUxMHhDb3VudHMocGFzdGUocGFyZW50X2RpcmVjdG9yeSwgcGFzdGUoc2FtcGxlX3BhdGhbaV0sICIvbmV3LW91dHMvY291bnRzL1NlbWlGaWx0ZXJlZENvdW50cyIsIHNlcCA9ICIiKSwgc2VwID0gIi8iKSwgc29ial9saXN0W1tpXV1AYXNzYXlzJFJOQSRjb3VudHMsIHZlcnNpb24gPSAiMyIsIG92ZXJ3cml0ZSA9IFRSVUUpCiAgICAgIH0gZWxzZSB7ICMgZWxzZSBtYWtlIGRpcmVjdG9yeSBhbmQgc2F2ZSBTZW1pIGZpbHRlcmVkIG1hdHJpeAogICAgICAgIGRpci5jcmVhdGUoZmlsZS5wYXRoKHBhc3RlKHBhcmVudF9kaXJlY3RvcnksIHBhc3RlKHNhbXBsZV9wYXRoW2ldLCAiL25ldy1vdXRzL2NvdW50cyIsIHNlcCA9ICIiKSwgc2VwID0gIi8iKSksIHJlY3Vyc2l2ZSA9IFRSVUUpCiAgICAgICAgd3JpdGUxMHhDb3VudHMocGFzdGUocGFyZW50X2RpcmVjdG9yeSwgcGFzdGUoc2FtcGxlX3BhdGhbaV0sICIvbmV3LW91dHMvY291bnRzL1NlbWlGaWx0ZXJlZENvdW50cyIsIHNlcCA9ICIiKSwgc2VwID0gIi8iKSwgc29ial9saXN0W1tpXV1AYXNzYXlzJFJOQSRjb3VudHMsIHZlcnNpb24gPSAiMyIsIG92ZXJ3cml0ZSA9IFRSVUUpCiAgICAgIH0KICB9IGVsc2UgewogICAgIyBmaWx0ZXIgb3V0IHRoZSBtdWx0aXBsZXRzCiAgICBjb2xuYW1lcyhzb2JqX2xpc3RbW2ldXUBtZXRhLmRhdGEpW2xlbmd0aChzb2JqX2xpc3RbW2ldXUBtZXRhLmRhdGEpXSA8LSAibXVsdGlwbGV0cyIgIyBNYWtlIGNvbG5hbWVzIG9mIG11bHRpcGxldCBjaGFubmVsIHVuaXZlcnNhbCBmb3IgYWxsIFNldXJhdCBvYmplY3RzCiAgICBzb2JqX2xpc3RbW2ldXSA8LSBzdWJzZXQoc29ial9saXN0W1tpXV0sIHN1YnNldCA9IG11bHRpcGxldHMgPT0gIlNpbmdsZXQiKSAjIHJlbW92ZSBkb3VibGV0cyBieSBrZWVwaW5nICJzaW5nbGV0cyIKICAgIHByaW50KHNvYmpfbGlzdFtpXSkKICAgICMgU2F2ZSB0aGUgZmluYWwgY29ycmVjdGVkIE1hdHJpeAogICAgaWYgKGRpci5leGlzdHMoZmlsZS5wYXRoKHBhc3RlKHBhcmVudF9kaXJlY3RvcnksIHBhc3RlKHNhbXBsZV9wYXRoW2ldLCAiL25ldy1vdXRzL2NvdW50cyIsIHNlcCA9ICIiKSwgc2VwID0gIi8iKSkpKSB7CiAgICAgIHdyaXRlMTB4Q291bnRzKHBhc3RlKHBhcmVudF9kaXJlY3RvcnksIHBhc3RlKHNhbXBsZV9wYXRoW2ldLCAiL25ldy1vdXRzL2NvdW50cy9GaWx0ZXJlZENvdW50cyIsIHNlcCA9ICIiKSwgc2VwID0gIi8iKSwgc29ial9saXN0W1tpXV1AYXNzYXlzJFJOQSRjb3VudHMsIHZlcnNpb24gPSAiMyIsIG92ZXJ3cml0ZSA9IFRSVUUpCiAgICAgIH0gZWxzZSB7CiAgICAgICAgZGlyLmNyZWF0ZShmaWxlLnBhdGgocGFzdGUocGFyZW50X2RpcmVjdG9yeSwgcGFzdGUoc2FtcGxlX3BhdGhbaV0sICIvbmV3LW91dHMvY291bnRzIiwgc2VwID0gIiIpLCBzZXAgPSAiLyIpKSwgcmVjdXJzaXZlID0gVFJVRSkKICAgICAgICB3cml0ZTEweENvdW50cyhwYXN0ZShwYXJlbnRfZGlyZWN0b3J5LCBwYXN0ZShzYW1wbGVfcGF0aFtpXSwgIi9uZXctb3V0cy9jb3VudHMvRmlsdGVyZWRDb3VudHMiLCBzZXAgPSAiIiksIHNlcCA9ICIvIiksIHNvYmpfbGlzdFtbaV1dQGFzc2F5cyRSTkEkY291bnRzLCB2ZXJzaW9uID0gIjMiLCBvdmVyd3JpdGUgPSBUUlVFKQogICAgICB9CiAgICB9CiAgfQoKIyMjIyMjIyMjIyBGdW5jdGlvbiAjIyMjIyMjIyMjIAojIC8vIFRoaXMgZnVuY3Rpb24gcmV0dXJucyBRQyBwbG90cyBvZiB0aGUgcHJlIHByb2NjZXNlZCAoZmlsdGVyZWQpIFNldXJhdCBvYmplY3QKIyAvLyBSZXR1cm5zIGhpc3RvZ3JhbSBvZiBjZWxsIGZyZXF1ZW5jeSB2cyBNVCwgblVNSSBhbmQgbkdlbmUKIyAvLyBSZXR1cm4gYSB2aW9saW4gcGxvdCBvZiBjZWxsIGRpc3RyaWJ1dGlvbiBhcyBhIGZ1bmN0aW9uIG9mIE1UIGNvbmMsIG5VTUksIG5HZW5lIAojIC8vIFJldHVybiBhIHNjYXR0ZXIgcGxvdCBvZiBjZWxscyBiYXNlZCBvbiBuVU1JcyB2cyBuR2VuZXMgKGFsc28gaW4gTG9nMTAgc2NhbGVkKSAKIyAvLyBSZXR1cm4gYSBzY2F0dGVyIHBsb3Qgb2YgY2VsbHMgYmFzZWQgb24gJU1UIHZzIG5HZW5lcyBvciBuVU1JcwojIC8vIElucHV0IGZpbGUgbXVzdCBiZSBhIHZlY3RvciBvZiBTZXVyYXQgb2JqZWN0cyB0aGF0IGhhdmUgYmVlbiBwcmUgcHJvY2Vzc2VkCmdldF92aW9sX1FDIDwtIGZ1bmN0aW9uKHNvYmosIGZldS51cCwgdW1pLnVwLCBmZXUubG93LCB1bWkubG93KSB7CiAgc29iaiA8LSBTZXRJZGVudChzb2JqLCB2YWx1ZSA9IHNvYmpAbWV0YS5kYXRhJG9yaWcuaWRlbnQpICMgY2hhbmdlIGFjdGl2ZS5pZGVudCB0byBvcmlnLmlkZW50LCBhcyB0aGUgYWN0aXZlLmlkZW50IGhhcyBiZWVuIGNoYW5nZWQgYWZ0ZXIgdGhlIExvdmFpbiBjbHVzdGVyaW5nLgogIHYxIDwtIFZsblBsb3Qoc29iaiwgZmVhdHVyZXMgPSBjKCJuRmVhdHVyZV9STkEiLCAibkNvdW50X1JOQSIsICJwZXJjZW50Lm10IiksIG5jb2wgPSAzLCBjb2xzID0gIm1hZ2VudGEiKQogIAogIGFzX3RpYmJsZShzb2JqW1tdXSwgcm93bmFtZXM9IkNlbGwuQmFyY29kZSIpIC0+IHFjLm1ldHJpY3MgIyBzb2JqX2xpc3RbWzFdXVtbXV0gc2hvd3MgZGF0YS5mcmFtZSBvZiBtZXRhZGF0YQogIHAxIDwtIHFjLm1ldHJpY3MgJT4lCiAgICBhcnJhbmdlKHBlcmNlbnQubXQpICU+JQogICAgZ2dwbG90KGFlcyhuQ291bnRfUk5BLG5GZWF0dXJlX1JOQSwgY29sb3VyPXBlcmNlbnQubXQpKSArIAogICAgZ2VvbV9wb2ludCgpICsgCiAgICBzY2FsZV9jb2xvdXJfZ3JhZGllbnRuKGNvbG91cnMgPSBjKCdibGFjaycsICdibGFjaycsICdyZWQzJyksIHZhbHVlcyA9IGMoMCwgKCgobWF4KHNvYmpbWyJwZXJjZW50Lm10Il1dJHBlcmNlbnQubXQpICogOTUpIC8gMTAwKSAvIDEwKSwgMSkpICsKICAgIGdlb21fc21vb3RoKG1ldGhvZCA9ICJsbSIsIGNvbG9yID0gImdyZWVuIiwgc2l6ZT0xKSArIAogICAgZ2d0aXRsZShwYXN0ZSgiUE9TVC1GSUxURVJJTkc6IG5VTUlzIHZzIG5HZW5lcyB3aXRoIHBlcmNlbnQgTVQiLCBzb2JqQG1ldGEuZGF0YVsxLDFdLCBzZXAgPSAiIC0gIikpICsgCiAgICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSAyMDAsIGxpbmV0eXBlPSJkYXNoZWQiLCBjb2xvciA9ICJvcmFuZ2UiLCBzaXplPTAuNykgKwogICAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gZmV1LnVwLCBsaW5ldHlwZT0iZGFzaGVkIiwgY29sb3IgPSAieWVsbG93Iiwgc2l6ZT0wLjcpICsgCiAgICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSBmZXUubG93LCBsaW5ldHlwZT0iZGFzaGVkIiwgY29sb3IgPSAieWVsbG93Iiwgc2l6ZT0wLjcpICsgCiAgICBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSA1NTAsIGxpbmV0eXBlPSJkYXNoZWQiLCBjb2xvciA9ICJvcmFuZ2UiLCBzaXplPTAuNykgKwogICAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gdW1pLnVwLCBsaW5ldHlwZT0iZGFzaGVkIiwgY29sb3IgPSAieWVsbG93Iiwgc2l6ZT0wLjcpICsKICAgIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IHVtaS5sb3csIGxpbmV0eXBlPSJkYXNoZWQiLCBjb2xvciA9ICJ5ZWxsb3ciLCBzaXplPTAuNykgKwogICAgeWxhYigiTnVtYmVyIG9mIEdlbmVzIikgKyAKICAgIHhsYWIoIk51bWJlciBvZiBVTUlzIChSTkEgTW9sZWN1bGVzKSIpICsgCiAgICB0aGVtZV9idygpICsgIyBtYWtlIGZpbGxlciB3aGl0ZQogICAgdGhlbWUocGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfYmxhbmsoKSwgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfYmxhbmsoKSkgIyByZW1vdmUgcmFzdGVyCiAgCiAgICBwMS4xIDwtIHFjLm1ldHJpY3MgJT4lCiAgICBhcnJhbmdlKHBlcmNlbnQubXQpICU+JQogICAgZ2dwbG90KGFlcyhsb2cxMChuQ291bnRfUk5BKSwgbG9nMTAobkZlYXR1cmVfUk5BKSwgY29sb3VyPXBlcmNlbnQubXQpKSArIAogICAgZ2VvbV9wb2ludCgpICsgCiAgICBzY2FsZV9jb2xvdXJfZ3JhZGllbnRuKGNvbG91cnMgPSBjKCdibGFjaycsICdibGFjaycsICdyZWQzJyksIHZhbHVlcyA9IGMoMCwgKCgobWF4KHNvYmpbWyJwZXJjZW50Lm10Il1dJHBlcmNlbnQubXQpICogOTUpIC8gMTAwKSAvIDEwKSwgMSkpICsKICAgIGdlb21fc21vb3RoKG1ldGhvZCA9ICJsbSIsIGNvbG9yID0gImdyZWVuIiwgc2l6ZT0xKSArIAogICAgZ2d0aXRsZShwYXN0ZSgiUE9TVC1GSUxURVJJTkc6IExvZzEwIHNjYWxlZCBuVU1JcyB2cyBuR2VuZXMgd2l0aCBwZXJjZW50IE1UIikpICsgCiAgICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSBsb2cxMCgyMDApLCBsaW5ldHlwZT0iZGFzaGVkIiwgY29sb3IgPSAib3JhbmdlIiwgc2l6ZT0wLjcpICsKICAgIGdlb21faGxpbmUoeWludGVyY2VwdCA9IGxvZzEwKGZldS51cCksIGxpbmV0eXBlPSJkYXNoZWQiLCBjb2xvciA9ICJ5ZWxsb3ciLCBzaXplPTAuNykgKwogICAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gbG9nMTAoZmV1LmxvdyksIGxpbmV0eXBlPSJkYXNoZWQiLCBjb2xvciA9ICJ5ZWxsb3ciLCBzaXplPTAuNykgKyAKICAgIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IGxvZzEwKDU1MCksIGxpbmV0eXBlPSJkYXNoZWQiLCBjb2xvciA9ICJvcmFuZ2UiLCBzaXplPTAuNykgKwogICAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gbG9nMTAodW1pLnVwKSwgbGluZXR5cGU9ImRhc2hlZCIsIGNvbG9yID0gInllbGxvdyIsIHNpemU9MC43KSArCiAgICBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSBsb2cxMCh1bWkubG93KSwgbGluZXR5cGU9ImRhc2hlZCIsIGNvbG9yID0gInllbGxvdyIsIHNpemU9MC43KSArCiAgICB5bGFiKCJMb2cxMCAoTnVtYmVyIG9mIEdlbmVzKSIpICsgCiAgICB4bGFiKCJMb2cxMCAoTnVtYmVyIG9mIFVNSXMpIikgKyAKICAgIHRoZW1lX2J3KCkgKyAjIG1ha2UgZmlsbGVyIHdoaXRlCiAgICB0aGVtZShwYW5lbC5ncmlkLm1ham9yID0gZWxlbWVudF9ibGFuaygpLCBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9ibGFuaygpKSAgIyByZW1vdmUgcmFzdGVyCiAgCiAgICBoMSA8LSBoaXN0KHNvYmpbWyJwZXJjZW50Lm10Il1dJHBlcmNlbnQubXQsIGJyZWFrcyA9IDMwLCB4bGFiID0gIlBlcmNlbnRhZ2UgTWl0b2Nob25kcmlhbCBHZW5lcyAoJSkiLCB5bGFiID0gIkZyZXF1ZW5jeSAoY2VsbHMpIiwgCiAgICAgICAgICAgICBtYWluID0gcGFzdGUoIlBPU1QtRklMVEVSSU5HOiBRQyBNVCIsIHNvYmpAbWV0YS5kYXRhWzEsMV0sIHNlcCA9ICIgLSAiKSwgCiAgICAgICAgICAgICBjb2wgPSAid2hpdGUiLCBsYWJlbHMgPSBUUlVFLCBwbG90ID0gVFJVRSkKICAgIGFibGluZSh2ID0gMTAsIGNvbD0icmVkIiwgbHdkPTMsIGx0eT0yKQogICAgYWJsaW5lKHYgPSA1LCBjb2w9Im9yYW5nZSIsIGx3ZD0zLCBsdHk9MikKICAgICMgdmlzdWFsaXplIG51bWJlciBvZiBnZW5lcyBpbiBjZWxscwogICAgaDIgPC0gaGlzdChzb2JqW1sibkZlYXR1cmVfUk5BIl1dJG5GZWF0dXJlX1JOQSwgYnJlYWtzID0gMzAsIHhsYWIgPSAiTnVtYmVyIG9mIGdlbmVzIiwgeWxhYiA9ICJGcmVxdWVuY3kgKGNlbGxzKSIsIAogICAgICAgICAgICAgbWFpbiA9IHBhc3RlKCJQT1NULUZJTFRFUklORzogUUMgbnVtYmVyIG9mIGdlbmVzIiwgc29iakBtZXRhLmRhdGFbMSwxXSwgc2VwID0gIiAtICIpLCAKICAgICAgICAgICAgIGNvbCA9ICJ3aGl0ZSIsIGxhYmVscyA9IFRSVUUsIHBsb3QgPSBUUlVFKQogICAgYWJsaW5lKHYgPSAyMDAsIGNvbD0icmVkIiwgbHdkPTMsIGx0eT0yKQogICAgIyB2aXN1YWxpemUgbnVtYmVyIG9mIFVNSXMgKG1vbGVjdWxlcykgaW4gY2VsbHMKICAgIGgzIDwtIGhpc3Qoc29ialtbIm5Db3VudF9STkEiXV0kbkNvdW50X1JOQSwgYnJlYWtzID0gMzAsIHhsYWIgPSAiTnVtYmVyIG9mIFVNSXMgKFJOQSBtb2xlY3VsZXMpIiwgeWxhYiA9ICJGcmVxdWVuY3kgKGNlbGxzKSIsIAogICAgICAgICAgICAgbWFpbiA9IHBhc3RlKCJQT1NULUZJTFRFUklORzogUUMgbnVtYmVyIG9mIFVNSXMiLCBzb2JqQG1ldGEuZGF0YVsxLDFdLCBzZXAgPSAiIC0gIiksIAogICAgICAgICAgICAgY29sID0gIndoaXRlIiwgbGFiZWxzID0gVFJVRSwgcGxvdCA9IFRSVUUpCiAgICBhYmxpbmUodiA9IDUwMCwgY29sPSJyZWQiLCBsd2Q9MywgbHR5PTIpCiAgICAKICAgIGYuc2NhdC5wcm9jZXNzZWQgPC0gRmVhdHVyZVNjYXR0ZXIoc29iaiwgZmVhdHVyZTEgPSAibkZlYXR1cmVfUk5BIiwgZmVhdHVyZTIgPSAicGVyY2VudC5tdCIsIGNvbHMgPSAiYmxhY2siKSArIAogICAgZ2d0aXRsZShwYXN0ZSgiUE9TVC1GSUxURVJJTkc6IFBlcmNlbnQtTVQgdnMgbkdlbmVzIiwgc29iakBtZXRhLmRhdGFbMSwxXSwgc2VwID0gIiAtICIpKSArIAogICAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gMTAsIGxpbmV0eXBlPSJkYXNoZWQiLCBjb2xvciA9ICJyZWQiLCBzaXplPTEpICsKICAgIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDcuNSwgbGluZXR5cGU9ImRhc2hlZCIsIGNvbG9yID0gIm9yYW5nZSIsIHNpemU9MSkgKyAKICAgIHlsYWIoIlBlcmNlbnQgTXRpb2Nob25kcmlhbCBHZW5lcyAoJSkiKSArIAogICAgeGxhYigiTnVtYmVyIG9mIEdlbmVzIikgKyBOb0xlZ2VuZCgpICsgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpKQogICAgCiAgICBmLnNjYXQucHJvY2Vzc2VkMiA8LSBGZWF0dXJlU2NhdHRlcihzb2JqLCBmZWF0dXJlMSA9ICJuQ291bnRfUk5BIiwgZmVhdHVyZTIgPSAicGVyY2VudC5tdCIsIGNvbHMgPSAiYmxhY2siKSArIAogICAgZ2d0aXRsZShwYXN0ZSgiUE9TVC1GSUxURVJJTkc6IFBlcmNlbnQtTVQgdnMgblVNSXMiKSkgKyAKICAgIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDEwLCBsaW5ldHlwZT0iZGFzaGVkIiwgY29sb3IgPSAicmVkIiwgc2l6ZT0xKSArCiAgICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSA3LjUsIGxpbmV0eXBlPSJkYXNoZWQiLCBjb2xvciA9ICJvcmFuZ2UiLCBzaXplPTEpICsgCiAgICB5bGFiKCJQZXJjZW50IE10aW9jaG9uZHJpYWwgR2VuZXMgKCUpIikgKyAKICAgIHhsYWIoIk51bWJlciBvZiBVTUlzIChSTkEgTW9sZWN1bGVzKSIpICsgTm9MZWdlbmQoKSArIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1KSkKICAgIAogICAgCiAgICBzb2JqJGxvZzEwR2VuZXNQZXJVTUkgPC0gbG9nMTAoc29iaiRuRmVhdHVyZV9STkEpIC8gbG9nMTAoc29iaiRuQ291bnRfUk5BKQogICMgVmlzdWFsaXplIHRoZSBvdmVyYWxsIGNvbXBsZXhpdHkgb2YgdGhlIGdlbmUgZXhwcmVzc2lvbiBieSB2aXN1YWxpemluZyB0aGUgZ2VuZXMgZGV0ZWN0ZWQgcGVyIFVNSQogIHAxLjIgPC0gc29iakBtZXRhLmRhdGEgJT4lCiAgCWdncGxvdChhZXMobG9nMTBHZW5lc1BlclVNSSkpICsKICAJZ2VvbV9kZW5zaXR5KGFscGhhID0gMSwgY29sb3IgPSAib3JhbmdlIiwgc2l6ZT0xLjUpICsKICAJdGhlbWVfY2xhc3NpYygpICsKICAJZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gMC44LCBsaW5ldHlwZT0iZGFzaGVkIiwgY29sb3IgPSAicmVkIiwgc2l6ZT0xKSArCiAgICBnZ3RpdGxlKHBhc3RlKCJDb21wbGV4aXR5IFBsb3Q6Iiwgc29iakBtZXRhLmRhdGFbMSwxXSwgc2VwID0gIiAiKSkgKyAKICAgIHlsYWIoIkRlbnNpdHkiKSArIAogICAgeGxhYigiTG9nMTAgR2VuZXMvVU1JIChHZW5lcyBwZXIgVU1JKSIpCiAgCiAgIyBMZXQgdGFrZSBhIGNsb3NlciBsb29rIGF0IHRoZSBjb21wbGV4aXR5IG9mIHRoZSBkYXRhIGFuZCBkcml2ZW4gYnkgd2hhdCBnZW5lLiAKICAjIENhbGN1bGF0ZSBjYWxjdWxhdGUgdGhlIGxvZzEwKG5GZWF0dXJlX1JOQSkgLyBsb2cxMChuQ291bnRfUk5BKSkgYW5kIHB1dCBpbiB0aGUgcWMubWV0cmljCiAgcWMubWV0cmljcyAlPiUKICBkcGx5cjo6bXV0YXRlKGNvbXBsZXhpdHk9bG9nMTAobkZlYXR1cmVfUk5BKSAvIGxvZzEwKG5Db3VudF9STkEpKSAgLT4gcWMubWV0cmljcwogICMgTWFrZSBsaW5lYXIgbW9kZWxzIG9mIGxvZzEwKG5GZWF1dHVyZXMpIHZzIExvZzEwKG5VTUlzKSBhbmQgcHV0IGluIHB1dCBpbiBjb21wbGV4aXR5LmxtCiAgIyBIZXJlLCB3ZSBjYWxjdWxhdGUgdGhlIGRpZmZlcmVuY2UgZnJvbSB0aGUgb2JzZXJ2ZWQgdmFsdWUgdG8gdGhlIGV4cGVjdGVkCiAgbG0obG9nMTAocWMubWV0cmljcyRuRmVhdHVyZV9STkEpfmxvZzEwKHFjLm1ldHJpY3MkbkNvdW50X1JOQSkpIC0+IGNvbXBsZXhpdHkubG0KICAjIENhbGN1bGF0ZSB0aGUgY29tcGxleGl0eSBmcm9tIHRoZSBtaWRkbGUgbGluZSBvZiB0aGUgbGluZWFyIG1vZGVsCiAgIyBXZSB3aWxsIHVzZSB0aGlzIGZvciB0aGUgY29sb3Igc2NhbGUgb2YgdGhlIGdyYXBoIGFzIHdlbGwuCiAgcWMubWV0cmljcyAlPiUKICBkcGx5cjo6bXV0YXRlKGNvbXBsZXhpdHlfZGlmZiA9IGxvZzEwKG5GZWF0dXJlX1JOQSkgLSAoKGxvZzEwKHFjLm1ldHJpY3MkbkNvdW50X1JOQSkqY29tcGxleGl0eS5sbSRjb2VmZmljaWVudHNbMl0pK2NvbXBsZXhpdHkubG0kY29lZmZpY2llbnRzWzFdKQogICkgLT4gcWMubWV0cmljcwogICMgRmluZCB0aGUgZGVsdGEgZGlmZmVyZW5jZSBmb3IgdGhlIGdyYXBoCiAgbWluKGMobWF4KHFjLm1ldHJpY3MkY29tcGxleGl0eV9kaWZmKSwwLW1pbihxYy5tZXRyaWNzJGNvbXBsZXhpdHlfZGlmZikpKSAtPiBjb21wbGV4aXR5X3NjYWxlCgogICMgSGVyZSB3ZSB2aXN1YWxpemUgdGhlIHRoZSBkYXRhIGNvbXBsZXhpdHkgKGNlbGxzKSBiYXNlZCBvbiB0aGUgY2FsY3VsYXRpb25zIGFib3ZlCiAgcDEuMyA8LSBxYy5tZXRyaWNzICU+JSAKICBkcGx5cjo6bXV0YXRlKGNvbXBsZXhpdHlfZGlmZj1yZXBsYWNlKGNvbXBsZXhpdHlfZGlmZixjb21wbGV4aXR5X2RpZmY8IC0wLjUsLTAuNSkpICU+JQogIGdncGxvdChhZXMoeD1sb2cxMChuQ291bnRfUk5BKSwgeT1sb2cxMChuRmVhdHVyZV9STkEpLCBjb2xvdXI9Y29tcGxleGl0eV9kaWZmKSkgKwogIGdlb21fcG9pbnQoKSArCiAgZ2VvbV9hYmxpbmUoc2xvcGU9Y29tcGxleGl0eS5sbSRjb2VmZmljaWVudHNbMl0sIGludGVyY2VwdCA9IGNvbXBsZXhpdHkubG0kY29lZmZpY2llbnRzWzFdKSArCiAgc2NhbGVfY29sb3VyX2dyYWRpZW50Mihsb3c9ImJsdWUyIixtaWQ9ImdyZXkiLGhpZ2g9InJlZDIiKSArCiAgZ2d0aXRsZShwYXN0ZSgiQ29tcGxleGl0eTogTG9nMTAgLSBuVU1JcyB2cyBuR2VuZXMiLCBzb2JqQG1ldGEuZGF0YVsxLDFdLCBzZXAgPSAiIC0gIikpICsgCiAgeWxhYigiTG9nMTAgKE51bWJlciBvZiBHZW5lcykiKSArIAogIHhsYWIoIkxvZzEwIChOdW1iZXIgb2YgVU1JcykiKSArIAogIHRoZW1lX2J3KCkgKyAKICB0aGVtZShwYW5lbC5ncmlkLm1ham9yID0gZWxlbWVudF9ibGFuaygpLCBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9ibGFuaygpKQoKICAjIEhlcmUgd2UgdmlzdWFsaXplIHRoZSBkZW5zaXR5IHBsb3Qgb2YgdGhlIGNlbGxzIGZyb20gdGhlIG1pZGRsZSBvZiB0aGUgbGluZWFyIGdyYXBoIGZyb20gUDEuMwogIHAxLjQgPC0gcWMubWV0cmljcyAlPiUgZ2dwbG90KGFlcyh4PWNvbXBsZXhpdHlfZGlmZikpICsgCiAgZ2VvbV9kZW5zaXR5KGZpbGw9InllbGxvdyIpICsKICBnZ3RpdGxlKHBhc3RlKCJSZXNpZHVhbCB2cyBEZW5zaXR5IikpICsgCiAgeWxhYigiRGVuc2l0eSIpICsgCiAgeGxhYigiQ29tcGxleGl0eSBEaWZmZXJlbmNlIChSZXNpZHVhbHMpIikgKyAKICB0aGVtZV9idygpICsgCiAgdGhlbWUocGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfYmxhbmsoKSwgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfYmxhbmsoKSkKICAKICAjIE5vdyBsZXRzIHdoaWNoIGdlbmVzIGFyZSBhY3R1YWxseSBkcml2aW5nIHRoZSBsb3cgY29tcGxleGl0eSBjZWxscyBpbiB0aGUgZGF0YQogICMgRm9yIHRoaXMsIHdlIGZpcnN0IGNhbGN1bGF0ZSB0aGUgcGVyY2VudGFnZSBvZiBsYXJnZXN0IGdlbmVzLgogICMgRmluZCB0aGUgY2VsbHMgd2l0aCBsYXJnZXN0IGNvdW50cwogIHFjLm1ldHJpY3MgJT4lIG11dGF0ZShsYXJnZXN0X2NvdW50ID0gYXBwbHkoc29iakBhc3NheXMkUk5BQGxheWVycyRjb3VudHMsIDIsIG1heCkpIC0+IHFjLm1ldHJpY3MgIyAiMiIgaXMgdG8gcmV0dXJuIG1heCBjb2x1bW5zIHZhbHVlcwogICMgZmluZCB0aGUgaW5kZXggb2YgdGhlIGNlbGwgd2l0aCBsYXJnZXN0IGNvdW50cwogIHFjLm1ldHJpY3MgJT4lIG11dGF0ZShsYXJnZXN0X2luZGV4ID0gYXBwbHkoc29iakBhc3NheXMkUk5BQGxheWVycyRjb3VudHMsIDIsIHdoaWNoLm1heCkpIC0+IHFjLm1ldHJpY3MKICAjIFVzZSB0aGUgaW5kZXggYW5kIGdldCB0aGUgZ2VuZSBuYW1lIHRoYXQgYWNjb3VudHMgZm9yIHRoZSBsYXJnZXN0IGNvdW50cyBwZXIgY2VsbAogIHFjLm1ldHJpY3MgJT4lIG11dGF0ZShsYXJnZXN0X2dlbmUgPSByb3duYW1lcyhzb2JqKVtsYXJnZXN0X2luZGV4XSkgLT4gcWMubWV0cmljcwogICMgTm93IGNhbGN1bGF0ZSB0aGUgcGVyY2VudGFnZSByZWxhdGl2ZSB0byB0aGUgdG90YWwgY291bnRzIGluIHRoZSBkYXRhCiAgcWMubWV0cmljcyAlPiUgbXV0YXRlKHBlcmNlbnQuTGFyZ2VzdC5HZW5lID0gIDEwMCAqIGxhcmdlc3RfY291bnQgLyBuQ291bnRfUk5BKSAtPiBxYy5tZXRyaWNzCiAgCiAgIyBWaXN1YWxpemUgdGhlIGNvbXBsZXhpdHkgZXhwbGFpbmVkIGJ5IHBlcmNlbnRhZ2Ugb2YgbGFyZ2VzdCBnZW5lcwogIHAxLjUgPC0gcWMubWV0cmljcyAlPiUgZ2dwbG90KGFlcyh4PWNvbXBsZXhpdHlfZGlmZiwgeT1wZXJjZW50Lkxhcmdlc3QuR2VuZSkpICsgCiAgICBnZW9tX3BvaW50KCkgKwogICAgZ2d0aXRsZShwYXN0ZSgiUmVzaWR1YWxzIHZzIFBlcmNlbnRhZ2UgTGFyZ2VzdCBHZW5lcyIpKSArIAogICAgeWxhYigiUGVyY2VudGFnZSBMYXJnZXN0IEdlbmUgKCUpIikgKyAKICAgIHhsYWIoIkNvbXBsZXhpdHkgRGlmZmVyZW5jZSAoUmVzaWR1YWxzKSIpICsgCiAgICB0aGVtZV9idygpICsgCiAgICB0aGVtZShwYW5lbC5ncmlkLm1ham9yID0gZWxlbWVudF9ibGFuaygpLCBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9ibGFuaygpKQogIAogICMgU29ydCB0aGUgcGVyY2VudGFnZSBsYXJnZXN0IGdlbmVzIAogIHFjLm1ldHJpY3MgJT4lCiAgZHBseXI6Omdyb3VwX2J5KGxhcmdlc3RfZ2VuZSkgJT4lIGRwbHlyOjphcnJhbmdlKGRlc2MocGVyY2VudC5MYXJnZXN0LkdlbmUpKSAtPiBsYXJnZXN0X2dlbmVfbGlzdAogICMgRmlsdGVyIG91dCB0aGUgZ2VuZXMgPjUlIGNvdW50cyAKICBsYXJnZXN0X2dlbmVfbGlzdCAlPiUKICBkcGx5cjo6ZmlsdGVyKHBlcmNlbnQuTGFyZ2VzdC5HZW5lID4gMC41KSAlPiUgIyBmaWx0ZXIgZXhpc3RzIGluIG90aGVyIHBhY2thZ2VzLCB1c2UgZHBseXI6OiB0byBmaXgKICBkcGx5cjo6cHVsbChsYXJnZXN0X2dlbmUpIC0+IGxhcmdlc3RfZ2VuZXNfdG9fcGxvdAogIGxhcmdlc3RfZ2VuZXNfdG9fcGxvdCA8LSB1bmlxdWUobGFyZ2VzdF9nZW5lc190b19wbG90KVsxOjhdICMgUmVtb3ZlIGR1cGxpY2F0ZWQgZ2VuZSBuYW1lcyBhbmQgdGFrZSB1cCB0byAxMCBnZW5lcwogIAogICMgUGxvdCB0aGUgbGluZWFyIGNvbXBsZXhpdHkgbW9kZWwgdGhhdCBleHBsYWluIHRoZSBkZXZpYXRpb24gYnkgdGhlIGxhcmdlc3QgZ2VuZXMKICBwMS42IDwtIHFjLm1ldHJpY3MgJT4lCiAgZHBseXI6OmZpbHRlcihsYXJnZXN0X2dlbmUgJWluJSBsYXJnZXN0X2dlbmVzX3RvX3Bsb3QpICU+JQogIGRwbHlyOjptdXRhdGUobGFyZ2VzdF9nZW5lPWZhY3RvcihsYXJnZXN0X2dlbmUsIGxldmVscz1sYXJnZXN0X2dlbmVzX3RvX3Bsb3QpKSAlPiUKICBkcGx5cjo6YXJyYW5nZShsYXJnZXN0X2dlbmUpICU+JQogIGdncGxvdChhZXMoeD1sb2cxMChuQ291bnRfUk5BKSwgeT1sb2cxMChuRmVhdHVyZV9STkEpLCBjb2xvdXI9bGFyZ2VzdF9nZW5lKSkgKwogIGdlb21fcG9pbnQoc2l6ZT0xLjUpICsKICBnZW9tX2FibGluZShzbG9wZT1jb21wbGV4aXR5LmxtJGNvZWZmaWNpZW50c1syXSwgaW50ZXJjZXB0ID0gY29tcGxleGl0eS5sbSRjb2VmZmljaWVudHNbMV0pICsgI2ltcG9ydCB0aGUgbGluZSBmb3JtIGxpbmVhciBtb2RlbCBmcm9tIGJlZm9yZQogIGdlb21faGxpbmUoeWludGVyY2VwdCA9IGxvZzEwKDIwMCksIGxpbmV0eXBlPSJkYXNoZWQiLCBjb2xvciA9ICJvcmFuZ2UiLCBzaXplPTAuNykgKwogIGdlb21faGxpbmUoeWludGVyY2VwdCA9IGxvZzEwKGZldS51cCksIGxpbmV0eXBlPSJkYXNoZWQiLCBjb2xvciA9ICJ5ZWxsb3ciLCBzaXplPTAuNykgKwogIGdlb21faGxpbmUoeWludGVyY2VwdCA9IGxvZzEwKGZldS5sb3cpLCBsaW5ldHlwZT0iZGFzaGVkIiwgY29sb3IgPSAieWVsbG93Iiwgc2l6ZT0wLjcpICsgCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gbG9nMTAoNTUwKSwgbGluZXR5cGU9ImRhc2hlZCIsIGNvbG9yID0gIm9yYW5nZSIsIHNpemU9MC43KSArCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gbG9nMTAodW1pLnVwKSwgbGluZXR5cGU9ImRhc2hlZCIsIGNvbG9yID0gInllbGxvdyIsIHNpemU9MC43KSArCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gbG9nMTAodW1pLmxvdyksIGxpbmV0eXBlPSJkYXNoZWQiLCBjb2xvciA9ICJ5ZWxsb3ciLCBzaXplPTAuNykgKwogIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzPWMoImdyZXkiLFJDb2xvckJyZXdlcjo6YnJld2VyLnBhbCg5LCJTZXQxIikpKSArCiAgZ2d0aXRsZShwYXN0ZSgiQ29tcGxleGl0eSBieSBMYXJnZXN0IEdlbmUiLCBzb2JqQG1ldGEuZGF0YVsxLDFdLCBzZXAgPSAiIC0gIikpICsgCiAgeWxhYigiTG9nMTAgKE51bWJlciBvZiBHZW5lcykiKSArIAogIHhsYWIoIkxvZzEwIChOdW1iZXIgb2YgVU1JcykiKSArIAogIHRoZW1lX2J3KCkgKyAKICB0aGVtZShwYW5lbC5ncmlkLm1ham9yID0gZWxlbWVudF9ibGFuaygpLCBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9ibGFuaygpKSAKICAgIAogICMgTm93IHBsb3QgYSBzY2F0dGVyIG9mIHRoZSBjZWxscyB3aXRoIHRoZSByZXNpZHVhbHMgb24gdGhlIHgtYXhpcyBhbmQgcGVyY2VudGFnZSBsYXJnZXN0IGdlbmUgaW4gdGhlIHktYXhpcwogIHAxLjcgPC0gcWMubWV0cmljcyAlPiUKICBkcGx5cjo6ZmlsdGVyKGxhcmdlc3RfZ2VuZSAlaW4lIGxhcmdlc3RfZ2VuZXNfdG9fcGxvdCkgJT4lCiAgZHBseXI6Om11dGF0ZShsYXJnZXN0X2dlbmU9ZmFjdG9yKGxhcmdlc3RfZ2VuZSwgbGV2ZWxzPWxhcmdlc3RfZ2VuZXNfdG9fcGxvdCkpICU+JQogIGRwbHlyOjphcnJhbmdlKGxhcmdlc3RfZ2VuZSkgJT4lCiAgZ2dwbG90KGFlcyh4PWNvbXBsZXhpdHlfZGlmZiwgeT1wZXJjZW50Lkxhcmdlc3QuR2VuZSwgY29sb3VyPWxhcmdlc3RfZ2VuZSkpICsKICBnZW9tX3BvaW50KHNpemU9MS41KSArCiAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXM9YygiZ3JleSIsUkNvbG9yQnJld2VyOjpicmV3ZXIucGFsKDksIlNldDEiKSkpICsgCiAgZ2d0aXRsZShwYXN0ZSgiUmVzaWR1YWwgdnMgUGVyY2VudGFnZSBMYXJnZXN0IEdlbmVzIikpICsgCiAgeWxhYigiUGVyY2VudGFnZSBMYXJnZXN0IEdlbmUgKCUpIikgKyAKICB4bGFiKCJDb21wbGV4aXR5IERpZmZlcmVuY2UgKFJlc2lkdWFscykiKSArIAogIHRoZW1lX2J3KCkgKyAKICB0aGVtZShwYW5lbC5ncmlkLm1ham9yID0gZWxlbWVudF9ibGFuaygpLCBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9ibGFuaygpKQogIAogICMgU2FtZSBhcyBhYm92ZSwgYnV0IG5vdyB3aXRoIHBlcmNlbnRhZ2UuTVQgYXMgZ3JhZGllbnQKICBwMS44IDwtIHFjLm1ldHJpY3MgJT4lCiAgYXJyYW5nZShwZXJjZW50Lm10KSAlPiUKICBnZ3Bsb3QoYWVzKHg9Y29tcGxleGl0eV9kaWZmLCB5PXBlcmNlbnQuTGFyZ2VzdC5HZW5lLCBjb2xvdXI9cGVyY2VudC5tdCkpICsKICBnZW9tX3BvaW50KCkgKwogIHNjYWxlX2NvbG91cl9ncmFkaWVudG4oY29sb3VycyA9IGMoJ2JsYWNrJywgJ2JsYWNrJywgJ3JlZDMnKSwgdmFsdWVzID0gYygwLCAoKChtYXgoc29ialtbInBlcmNlbnQubXQiXV0kcGVyY2VudC5tdCkgKiA5NSkgLyAxMDApIC8gMTApLCAxKSkgKwogIGdndGl0bGUocGFzdGUoIlJlc2lkdWFscyB2cyBQZXJjZW50YWdlIExhcmdlc3QgR2VuZXMgKyBNVCAlIikpICsgCiAgeWxhYigiUGVyY2VudGFnZSBMYXJnZXN0IEdlbmUgKCUpIikgKyAKICB4bGFiKCJDb21wbGV4aXR5IERpZmZlcmVuY2UgKFJlc2lkdWFscykiKSArIAogIHRoZW1lX2J3KCkgKyAKICB0aGVtZShwYW5lbC5ncmlkLm1ham9yID0gZWxlbWVudF9ibGFuaygpLCBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9ibGFuaygpKQogICAgCiAgIyBQcmludCB0aGUgcGxvdHMKICBwcmludCh2MSkKICBwcmludChmLnNjYXQucHJvY2Vzc2VkICsgZi5zY2F0LnByb2Nlc3NlZDIpCiAgcHJpbnQocDEgKyBwMS4xKQogIHByaW50KHAxLjIpCiAgcHJpbnQocDEuMyArIHAxLjQgKyBwMS41KQogIHByaW50KHAxLjYgKyBwMS43ICsgcDEuOCkKICAKICByZXR1cm4oKQp9CgojIEFwcGx5IGZ1bmN0aW9uIGdldF92aW9sX1FDCiN2aW9sIDwtIHNhcHBseShzb2JqX2xpc3QsIGdldF92aW9sX1FDKQp2aW9sIDwtIG1hcHBseShnZXRfdmlvbF9RQywgc29ial9saXN0LCBmZWF0dXJlLnF1YW50aWxlLmFibGluZSwgVU1JLnF1YW50aWxlLmFibGluZSwgZmVhdHVyZS5xdWFudGlsZS5hYmxpbmUubG93LCBVTUkucXVhbnRpbGUuYWJsaW5lLmxvdykgIyBtYXBwbHkgZm9yIG11bHRpcGxlIHZhcmlhYmxlcyBhcyB2ZWN0b3JzCmBgYAo=